2012-10-15 34 views
0

好的首先我要说的是,我所想的是创建属性并使用该属性来自动创建用该属性装饰的类的实例。真的有可以在我的情况下构建的类的实现,我不想在这里使用IoC容器,因为首先我认为它们不会被创建直到被请求为止,其次这仅适用于需要自动实例化的特殊类集主要是服务类。下面是用于创建单如何在NET程序集中自动初始化任何类

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上的代码片段,我认为它非常有趣,但没有设法启动类。

+2

请求时实例化的类有什么问题?单身人士的广泛使用将会长期困扰你 – lboshuizen

+0

那些只是每个模块的服务类别,所以这不是用于这种类型的类别的最小数目。 这里的问题是在哪里关闭firtordefualt方法其条件什么也没有返回 –

+1

'RuntimeHelpers.RunClassConstructor' – SLaks

回答

1

在对该类进行任何引用之前,可以使用静态构造函数来运行特定类的代码。以下是来自MS的一些信息:http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.100).aspx

编辑:Jon Skeet has an article on this subject可能会回答你的问题。它也有代码示例。

+0

是的但是你必须首先创建该类型的实例以首先激活静态构造函数,并且MSDN声明静态构造函数在创建任何实例之前仅声明一次,但这并不意味着它将自行执行甚至没有提到实例 –

+0

静态构造函数总是被执行,所以启动你的单例有一个很好的钩子 – lboshuizen

+0

你能看看代码并提供示例实例吗?我没有创建单例类的问题,但只能自动初始化它们,我测试了静态构造函数,并且在执行期间静态构造函数中没有制动点命中。 –