我希望使用WithMappings.FromMatchingInterface约定将实现特定接口的所有类注册到Unity中.另外,我希望使用接口拦截行为拦截所有已注册的对象.问题是Unity还注册了具体类之间的映射,当这些类被解析时,会抛出一个异常消息:
"[类型]不可拦截"
我意识到使用具体类类型解析对象不是最佳实践,但我想知道为什么Unity会自动为接口添加映射 - >具体类以及具体类 - >按惯例注册时的具体类?这意味着如果添加接口拦截器并使用具体类型解析它将永远不会工作.
我希望得到的结果是Unity在按惯例注册并给它一个接口拦截器时没有添加具体类型 - >具体类型映射,这样我们就可以使用它的具体类型来解析类,如果我们愿意,我们只是没有拦截.
我不想使用VirtualMethodInterceptor因为我不想对类进行更改以便拦截工作,这包括继承MarshalByRef.我还想避免单独注册所有对象.
因此,我的问题是,如何按惯例注册时只注册接口映射?
更新:单独注册类会产生相同的问题,因此假设一旦对象使用interfaceinterceptor注册,则无法通过使用具体类型来解析它.
新注册码:
container.RegisterType<ISomeService, SomeService>(new InjectionMember[]
{
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<TraceInterceptor>()
});
container.RegisterType<ISomeRepository, SomeRepository>(new InjectionMember[]
{
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<TraceInterceptor>()
});
Run Code Online (Sandbox Code Playgroud)
更新2为所有接口添加默认拦截器似乎工作,虽然这个解决方案相当hacky.该解决方案在按惯例进行标准注册之前需要一些代码,并且InterfaceInterceptor在基于约定的注册中删除.
预注册代码
foreach (var type in types)
{
container
.Configure<Interception>()
.SetDefaultInterceptorFor(type.GetInterface("I" + type.Name), new InterfaceInterceptor());
}
Run Code Online (Sandbox Code Playgroud)
一些解释困境的代码:
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using System;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{ …Run Code Online (Sandbox Code Playgroud)