gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 17:46:59 27 4
gpt4 key购买 nike

我想实现的是:

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

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

没有执行 IFooFactory 的地方- 因为它由 FactoryInterceptionBehavior 提供.

当我尝试解析 IFooFactory然而,我得到一个 ResolutionFailedException附留言:

InvalidOperationException - The current type, IFooFactory, is an interface and cannot be constructed. Are you missing a type mapping?

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

最佳答案

经过一些研究和反复试验后,我发现 Unity.Interception不支持没有实际类实现接口(interface)和调用最终结束的接口(interface)代理(城堡动态代理称它们为“没有目标的接口(interface)代理”)。

所以我所做的是使用 Castle.Core动态代理结合 unity 开箱即用的 InjectionFactory(可用于将解析委托(delegate)给 Func 工厂)。

注入(inject)工厂看起来像这样:

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

并且可以像这样在绑定(bind)中使用:

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 未涵盖的已解析(创建)实例的任何构造函数参数都是“照常”的构造函数注入(inject)。

关于c# - 自动生成接口(interface)的实现(没有类的代理),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25324178/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com