2012-10-15 6 views
0

Ok 우선 무엇보다도 생각해 볼 것은 속성을 만들고 해당 특성을 사용하여 해당 특성으로 장식 된 클래스의 인스턴스를 자동으로 만드는 것입니다. 내 상황에서 구현할 수있는 클래스의 구현이 실제로 있고 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에서 코드 조각을 발견했으며 정말 재미 있지만 init 클래스를 관리하지 못했다고 생각합니다.

+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

코드를보고 샘플 인스턴스를 제공 할 수 있습니까? 싱글 톤 클래스를 만드는 데 문제가 없지만 자동으로 초기화해야하며 정적 생성자를 테스트했으며 실행 중에 정적 생성자 내부에 브레이크 포인트 히트가 없습니다. –

관련 문제