【问题标题】:Unity Interception From Base Class来自基类的 Unity 拦截
【发布时间】:2014-09-05 20:32:07
【问题描述】:

我想针对特定的基类型向 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>()
);

ReportAttributePolicy 是我自定义的AttributeDrivenPolicy 版本。有关详细信息,请参阅我的 Unity Interception 博客文章。

很明显,我正在尝试制作的场景是这样的:

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

尽管请求的类型仅派生自 RootController,但我希望解析后的类型能够根据我的 ReportAttributePolicy 使用 AOP 日志记录。

当我执行上述代码时,我的 ReportAttributePolicy 上的任何方法都不会执行。这意味着我没有机会让魔法发生。如果我不处理继承示例,那么一切正常。

如何让它与继承一起工作?

【问题讨论】:

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


    【解决方案1】:

    当您调用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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多