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

本文关键字:代理 接口 实现 自动生成 | 更新日期: 2023-09-27 18:18:03

我想实现的是:

[Factory]
public interface IFooFactory
{
    Foo Create();
}
unityContainer.RegisterType<IFooFactory>(
    new Interceptor<InterfaceInterceptor>(), 
    new InterceptionBehavior<FactoryInterceptionBehavior>());

没有IFooFactory的实现-因为它是由FactoryInterceptionBehavior提供的。

当我试图解决IFooFactory然而,我得到一个ResolutionFailedException消息:

InvalidOperationException -当前类型IFooFactory是一个接口,不能构造。您是否错过了类型映射?

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

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

所以经过一些研究和试验& &;我发现了一个错误,Unity。在没有实际类实现接口和调用最终结束的情况下,拦截不支持接口代理(castle动态代理称之为"没有目标的接口代理")。

我使用的是Castle。核心动态代理与unity的开箱即用的InjectionFactory(可用于将分辨率委托给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看起来像:

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]));
    }

它通过名称匹配工厂方法参数和构造器参数(Unity开箱即用的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>();
}

还需要注意的是,任何被解析(创建)的实例的构造函数参数,如果没有被ParameterOverride所覆盖,则"像往常一样"进行ctor-inject。

相关文章: