自动生成接口的实现(没有类的代理)

时间:2014-08-15 09:31:41

标签: c# dependency-injection unity-container unity-interception

我想要达到的目标是:

[Factory]
public interface IFooFactory
{
    Foo Create();
}

unityContainer.RegisterType<IFooFactory>(
    new Interceptor<InterfaceInterceptor>(), 
    new InterceptionBehavior<FactoryInterceptionBehavior>());

没有IFooFactory的实施 - 因为FactoryInterceptionBehavior提供了它。

但是当我尝试解析IFooFactory时,我会收到ResolutionFailedException消息:

  

InvalidOperationException - 当前类型IFooFactory是一个   界面,不能构造。你错过了类型映射吗?

我还考虑过自己创建代理(使用Intercept.ThroughProxy<>或城堡动态代理...),但我仍然需要对容器进行类型注册。我不知道如何委托/覆盖这种类型的实例化(如Ninject&#39; s Bind<IFoo>().ToMethod(() => return new Foo()))。

1 个答案:

答案 0 :(得分:1)

经过一些研究和试验后,错误我发现,Unity.Interception不支持接口的代理,其中没有实现接口的实际类以及调用最终结束的地方(城堡动态代理调用它们&#34;接口代理没有目标&#34;。)

所以我所做的就是使用Castle.Core动态代理与统一的开箱即用的InjectionFactory(可用于将分辨率委托给{{1}工厂)。

注射工厂看起来像这样:

Func

并且可以在这样的绑定中使用:

var proxyFuncFactory = new InjectionFactory(CreateProxy);

private static object CreateProxy(IUnityContainer container, Type interfaceType, string name)
{
    var proxyGenerator = container.Resolve<Castle.DynamicProxy.ProxyGenerator>();

    return proxyGenerator.CreateInterfaceProxyWithoutTarget(interfaceType, container.Resolve<AutoGeneratedFactoryInterceptor>());
}

IUnityContainer.RegisterType<ISomeFactory>(proxyFuncFactory); 看起来像:

AutoGeneratedFactoryInterceptor

它将factory-method-argument与构造函数参数匹配(Unity开箱即用internal class AutoGeneratedFactoryInterceptor : IInterceptor { private readonly IUnityContainer _unityContainer; public AutoGeneratedFactoryInterceptor(IUnityContainer unityContainer) { _unityContainer = unityContainer; } public void Intercept(IInvocation invocation) { IEnumerable<ResolverOverride> resolverOverrides = DetermineResolverOverrides(invocation); Type typeToResolve = DetermineTypeToResolve(invocation.Method); invocation.ReturnValue = _unityContainer.Resolve(typeToResolve, resolverOverrides.ToArray()); } private static Type DetermineTypeToResolve(MethodInfo method) { ResolveToAttribute resolveToAttribute = method.Attribute<ResolveToAttribute>(); if (resolveToAttribute == null) { return method.ReturnType; } if (resolveToAttribute.ResolveTo.IsGenericTypeDefinition) { return resolveToAttribute.ResolveTo.MakeGenericType(method.GetGenericArguments()); } return resolveToAttribute.ResolveTo; } private static IEnumerable<ResolverOverride> DetermineResolverOverrides(IInvocation invocation) { return invocation.Method.Parameters() .Select((parameterInfo, parameterIndex) => new ParameterOverride(parameterInfo.Name, invocation.Arguments[parameterIndex])); } )。请注意,特别是通用参数支持并不完美。它支持以下用法:

ParameterOverride

public interface IFooFactory
{
    Foo Create();
}

unityContainer.RegisterType(typeof(IFoo<>), typeof(Foo<>));

public interface IFooFactory
{
    IFoo<T> Create<T>();
}

public interface IFooFactory
{
    Foo Create(string parameter1, object parameter2);
}

以及

public interface IFooFactory
{
    [ResolveTo(typeof(Foo))]
    IFoo Create();
}

另请注意,public interface IFooFactory { [ResolveTo(typeof(Foo<>))] IFoo Create<T>(); } 未涵盖的已解析(已创建)实例的任何构造函数参数都是ctor-inject&#34;像往常一样&#34;。