2014-09-05 71 views
1

我想爲Unity聲明對特定基類型的攔截,並且自動爲所有派生類型聲明攔截。從基類中的統一攔截

我看到了兩個不同的,所以帖子說是相同的話題,但也有我在尋找答案:

所以我想展示我的代碼,看看我能否得到特定於我的場景的答案。

我有這些類:

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派生,我想解決的類型與AOP測井儀器進行,根據我的ReportAttributePolicy

當我執行上面的代碼時,我的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);