来自基类的Unity拦截
本文关键字:Unity 拦截 基类 | 更新日期: 2023-09-27 18:20:46
我想为特定的基类型向Unity声明拦截,并让所有派生类型自动执行该拦截。
我看到两个不同的SO帖子是同一个主题,但都没有我想要的答案:
- Microsoft Unity基类拦截
这个告诉我已经知道的;这仍然是不够的信息 - 派生类中的Unity截取
这一个非常详细,但属于Unity配置,而不是我使用的命令形式
所以我想展示我的代码,看看我是否能得到一个特定于我的场景的答案。
我有这些课程:
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上的任何方法都不会执行。这意味着我没有机会创造奇迹。如果我不是在处理继承示例,那么一切都很好。
我如何使它与继承一起工作?
当您调用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);