因此,经过一些研究和反复试验,我发现Unity.Interception不支持没有实现接口的实际类以及调用最终结束的接口代理(城堡动态代理称它们为“没有接口代理”目标”)。
所以我所做的是使用Castle.Core动态代理与统一的开箱即用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]));
}
它按名称将 factory-method-argument 与 constructor-arguments 匹配(Unity out-of-the-box 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
's 覆盖,它们都是“像往常一样”的 ctor-inject。