1

我想为特定的基类型向 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.

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

我如何使它与继承一起工作?

4

1 回答 1

0

当您调用 时container.Resolve(...),Unity 会查找已配置的拦截器。如果不存在,则不执行拦截。此检查是对请求解析的类型进行的。由于您调用了 resolveMyController并且该类型没有配置拦截器,因此没有执行拦截。解决这个问题的唯一方法是注册所有派生自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);
于 2014-09-07T06:15:49.740 回答