0

わかりましたまず最初に、私が考えているのは、属性を作成し、その属性を使用して、その属性で装飾されたクラスのインスタンスを自動的に作成することです。私の状況で構築できるクラスの実装が実際にあり、ここで IoC コンテナーを使用したくないのは、最初に要求されるまで作成されないと思うからです。これらは主に Service クラスです。以下は、シングルトンの作成に使用されるコードの実装です

public abstract class Singleton<T> where T : class
{
    private readonly IEventAggregator _eventAggregator = 
        ServiceLocator.Current.GetInstance<IEventAggregator>();

    private static readonly Lazy<T> Instance
        = new Lazy<T>(() =>
                          {
                              ConstructorInfo[] ctors = typeof(T).GetConstructors(
                                  BindingFlags.Instance
                                  | BindingFlags.NonPublic
                                  | BindingFlags.Public);
                              if (ctors.Count() != 1)
                                  throw new InvalidOperationException(
                                      String.Format("Type {0} must have exactly one constructor.", typeof(T)));
                              ConstructorInfo ctor =
                                  ctors.SingleOrDefault(c => !c.GetParameters().Any() && c.IsPrivate);
                              if (ctor == null)
                                  throw new InvalidOperationException(
                                      String.Format(
                                          "The constructor for {0} must be private and take no parameters.",
                                          typeof(T)));
                              return (T)ctor.Invoke(null);
                          });

    public static T Current
    {
        get { return Instance.Value; }
    }
}

そして、ここにシングルトンとして定義されたサンプルクラスがあります

public class PersonService : Singleton<PersonService>, IPersonService
{
    private PersonService()
    {
        RegisterForEvent<PersonRequest>(OnPersonRequered);
        //_serviceClient = ServiceLocator.Current.GetInstance<ICuratioCMSServiceClient>();
    }
}

Hwre は、アクティブ化する必要があるすべてのタイプを解決するために使用されるコードが付属しています。

public class InitOnLoad : Attribute
{
    public static void Initialise()
    {
        // get a list of types which are marked with the InitOnLoad attribute
        var types =
            from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes())
            where t.GetCustomAttributes(typeof(InitOnLoad), false).Any()
            select t;

        // process each type to force initialize it
        foreach (var type in types)
        {
            // try to find a static field which is of the same type as the declaring class
            var field =
                type.GetFields(System.Reflection.BindingFlags.Static
                               | System.Reflection.BindingFlags.Public
                               | System.Reflection.BindingFlags.NonPublic
                               | System.Reflection.BindingFlags.Instance).FirstOrDefault(f => f.FieldType == type);
            // evaluate the static field if found
            //if (field != null) field.GetValue(null);
        }
    }
}

Stackoverflow でそのコードのフラグメントを見つけました。これは非常に興味深いと思いますが、クラスを初期化できませんでした。

4

1 に答える 1

1

静的コンストラクターを使用して、特定のクラスへの参照が行われる前にそのクラスのコードを実行できます。これに関するMSからの情報は次のとおりです:http: //msdn.microsoft.com/en-us/library/k9x6w0hc (v=vs.100).aspx 。

編集: Jon Skeet には、このテーマに関する記事があり、あなたの質問に答えるかもしれません。コードサンプルもあります。

于 2012-10-15T23:46:59.457 に答える