我想要达到的目标是:
[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())
)。
答案 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;。