基类的Unity拦截

时间:2014-09-05 20:32:07

标签: c# inheritance unity-container aop policy-injection

我想向Unity声明对特定基类型的拦截,并自动为所有派生类型保留该拦截。

我看到两个不同的SO帖子是同一主题,但我找不到答案:

所以我想展示我的代码,看看我是否能得到特定于我的情景的答案。

我有这些课程:

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

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

[Report]注释是我自己的自定义属性 - 它表示应该将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上没有任何方法被执行。这意味着我没有机会让魔术发生。如果我没有处理继承示例,那么一切正常。

如何使其继承?

1 个答案:

答案 0 :(得分:0)

当您致电container.Resolve(...)时,Unity会查找已配置的拦截器。如果没有,则不执行拦截。对于要求解决的类型,此检查已完成。由于您在MyController上调用了resolve并且该类型没有配置的拦截器,因此未执行拦截。解决这个问题的唯一方法是注册从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);
}

通过这些扩展以及按惯例方法注册的新Unity 3.0,注册和启用拦截的任务变得非常简单。

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

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

container.EnableInterception(controllers);