自动生成接口的实现(没有类的代理)
本文关键字:代理 接口 实现 自动生成 | 更新日期: 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。