c# - DryIoc open generic interception with castle core
问题描述
I want to register open generic interception, so I modified explample from https://github.com/dadhi/DryIoc/blob/master/docs/DryIoc.Docs/Interception.md
[TestFixture]
public class UnitTest3
{
public interface IFoo<T>
{
void Greet();
}
public class Foo<T> : IFoo<T>
{
public void Greet() { }
}
[Test]
public void Example()
{
var container = new Container();
container.Register(typeof(IFoo<>), typeof(Foo<>));
container.Register<FooLoggingInterceptor>(Reuse.Singleton);
container.Intercept<FooLoggingInterceptor>(typeof(IFoo<>));
var foo = container.Resolve<IFoo<int>>();
foo.Greet();
// examine that logging indeed was hooked up
var logger = container.Resolve<FooLoggingInterceptor>();
Assert.AreEqual("Invoking method: Greet", logger.LogLines[0]);
}
}
public class FooLoggingInterceptor : IInterceptor
{
public List<string> LogLines = new List<string>();
private void Log(string line) => LogLines.Add(line);
public void Intercept(IInvocation invocation)
{
Log($"Invoking method: {invocation.GetConcreteMethod().Name}");
invocation.Proceed();
}
}
public static class DryIocInterception
{
private static readonly DefaultProxyBuilder _proxyBuilder = new DefaultProxyBuilder();
public static void Intercept<TInterceptor>(this IRegistrator registrator, Type serviceType, object serviceKey = null)
where TInterceptor : class, IInterceptor
{
Type proxyType;
if (serviceType.IsInterface())
proxyType = _proxyBuilder.CreateInterfaceProxyTypeWithTargetInterface(
serviceType, ArrayTools.Empty<Type>(), ProxyGenerationOptions.Default); //Exception!!!
else if (serviceType.IsClass())
proxyType = _proxyBuilder.CreateClassProxyTypeWithTarget(
serviceType, ArrayTools.Empty<Type>(), ProxyGenerationOptions.Default);
else
throw new ArgumentException(
$"Intercepted service type {serviceType} is not a supported, cause it is nor a class nor an interface");
registrator.Register(serviceType, proxyType,
made: Made.Of(pt => pt.PublicConstructors().FindFirst(ctor => ctor.GetParameters().Length != 0),
Parameters.Of.Type<IInterceptor[]>(typeof(TInterceptor[]))),
setup: Setup.DecoratorOf(useDecorateeReuse: true, decorateeServiceKey: serviceKey));
}
}
But this throws exception:
Can not create proxy for type TestDryIoc.UnitTest3+IFoo`1 because type TestDryIoc.UnitTest3+IFoo`1 is an open generic type.
Aparently Castle.Core doesn't support open generics. My other idea was to supply delegate, which will create the proxy class on resolve, when concrete generic param is known, but looks like DryIoc doesn't support open generic delegates...
解决方案
是的,这是可能的。所以你需要找到封闭的类型来传递给代理吗?将代码包装到方法中并使用有权访问 Request.ServiceType 的 Made.Of。
推荐阅读
- algorithm - 最小化和差的绝对值
- ios - NSHealthUpdateUsageDescription 必须设置为 HKQuantityTypeIdentifierStepCount 请求写入授权
- python - 实例属性可以通过 ThreadPoolExecutor 调用的函数正确重置吗?
- javascript - 使用javascript计算总分
- bash - 按行拆分文件并将第一个字符串保留为输出文件的标题
- php - 如何将一些不规则数组管理为规则数组?
- kubernetes - GKE Ingress ERR_TIMEDOUT 的 HTTPS 请求
- c# - 'getNext' 没有重载匹配委托 'EventHandler'
- c++ - 获取指向非静态成员函数的函数指针
- python - 如何评估 1 == 2 == 2?