2014-09-05 7 views
1

특정 기본 유형에 대한 인터 셉션을 Unity에 선언하고 모든 파생 된 유형에 대해 자동으로 인터 셉션을 수행하고자합니다.기본 클래스로부터의 유니티 인터셉트

나는 동일한 주제 두 개의 서로 다른 SO 게시물을 볼 수 있지만, 어느 쪽도 내가 찾고 답이 없습니다 :

그래서 내가 갖고있는 코드를 보여주고 시나리오에 대한 답변을 얻을 수 있는지 확인하고 싶습니다.

나는이 수업을 :

public abstract class RootController 
{ 
    [Report] 
    public abstract void Action(); 
} 

public class MyController 
{ 
    public void Action() 
    { 
     Console.WriteLine("hey"); 
    } 
} 

에서 [리포트] 주석이 내 자신의 사용자 지정 특성 - 그것은 AOP 로깅 방법에 적용해야 나타냅니다. 다음과 같이이 정책 기반의 차단과 함께 사용하는 나는 준비 :

container.AddNewExtension<Interception>(); 

container.RegisterInstance<InjectionPolicy>(typeof(ReportAttributePolicy).AssemblyQualifiedName, new ReportAttributePolicy()); 

container.RegisterType<RootController>(
    new Interceptor<VirtualMethodInterceptor>(), 
    new InterceptionBehavior<PolicyInjectionBehavior>() 
); 

ReportAttributePolicyAttributeDrivenPolicy의 내 사용자 지정 버전입니다. 자세한 내용은 내 Unity Interception 블로그 게시물을 참조하십시오.

 var yup = container.Resolve<MyController>(); 

요청 유형은 단지 RootController에서 파생하더라도, 내가 해결 된 유형을 싶습니다 내 ReportAttributePolicy 당, AOP 로깅으로 계측 할 수 :

는 분명 내가이 작품을 만들기 위해 노력하고있어 시나리오는 이것이다 .

위 코드를 실행하면 내 ReportAttributePolicy의 메소드가 실행되지 않습니다. 이것은 내가 마술을 일으킬 기회가 없다는 것을 의미합니다. 상속 예제를 다루지 않는다면 모든 것이 잘 동작합니다.

어떻게하면 상속을 사용할 수 있습니까?

답변

0

container.Resolve(...)을 호출하면 Unity는 구성된 인터셉터를 찾습니다. 존재하지 않으면, 가로 채기가 수행되지 않습니다. 이 검사는을 해결하도록 요청 된 유형의 으로 수행됩니다. MyController에서 해결을 호출 했으므로 해당 유형에 구성된 인터셉터가 없으므로 차단이 수행되지 않았습니다. 이 문제를 해결하는 유일한 방법은 RootController에서 파생 된 모든 컨트롤러를 등록하고 인터셉터를 설정하는 것입니다. 나는 ...이 쉽게 이러한 확장으로

public static IUnityContainer EnableInterception<T>(this IUnityContainer container) 
{ 
    container.EnableInterception(typeof (T)); 
    return container; 
} 

public static IUnityContainer EnableInterception(this IUnityContainer container, Type type) 
{ 
    if (type.IsInterface) 
     container.Configure<Interception>().SetInterceptorFor(type, new InterfaceInterceptor()); 
    else 
     container.Configure<Interception>().SetInterceptorFor(type, new VirtualMethodInterceptor()); 
    return container; 
} 

public static IUnityContainer EnableInterception(this IUnityContainer container, IEnumerable<Type> types) 
{ 
    foreach (var type in types) 
    { 
     container.EnableInterception(type); 
    } 
    return container; 
} 

public static IEnumerable<Type> DerivedFrom<T>(this IEnumerable<Type> types) 
{ 
    return types.Where(t => typeof (T).IsAssignableFrom(t) && typeof (T) != t); 
} 

을 만들기 위해 몇 가지 헬퍼 메소드를 포함하고 컨벤션 방법으로 새로운 유니티 3.0 등록을, 등록 및 차단을 가능하게하는 작업은 매우 간단해진다.

var controllers = AllClasses.FromLoadedAssemblies().DerivedFrom<RootController>(); 

container.RegisterTypes(
    controllers, 
    WithMappings.None, 
    WithName.Default, 
    WithLifetime.Transient); 

container.EnableInterception(controllers);