gpt4 book ai didi

structuremap - 在约定中使用 CaSTLe DynamicProxy 和 StructureMap 3 进行装饰 - DecorateAllWith

转载 作者:行者123 更新时间:2023-12-04 20:40:54 26 4
gpt4 key购买 nike

使用方法DecorateAllWith用 DynamicProxy 装饰所有实例都实现了一个接口(interface)?

例如:

public class ApplicationServiceInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// ...
invocation.Proceed();
// ...
}
}

public class ApplicationServiceConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (type.CanBeCastTo<IApplicationService>() && type.IsInterface)
{
var proxyGenerator = new ProxyGenerator();

// ??? how to use proxyGenerator??
// ???

registry.For(type).DecorateAllWith(???); // How to use DecorateAllWith DynamicProxy ...??
}
}
}

我可以使用(例如)装饰一些具体类型的接口(interface):
var proxyGenerator = new ProxyGenerator();
registry.For<IApplicationService>().Use<BaseAppService>().DecorateWith(service => proxyGenerator.CreateInterfaceProxyWithTargetInterface(....))

但是还没有能够使用 DecorateAll 来做到这一点。

调用 registry.For<>().Use<>().DecorateWith()我必须这样做:
if (type.CanBeCastTo<IApplicationService>() && !type.IsAbstract)
{
var interfaceToProxy = type.GetInterface("I" + type.Name);
if (interfaceToProxy == null)
return null;
var proxyGenerator = new ProxyGenerator();

// Build expression to use registration by reflection
var expression = BuildExpressionTreeToCreateProxy(proxyGenerator, type, interfaceType, new MyInterceptor());

// Register using reflection
var f = CallGenericMethod(registry, "For", interfaceToProxy);
var u = CallGenericMethod(f, "Use", type);
CallMethod(u, "DecorateWith", expression);
}

只为疯狂的头脑...

我开始对 StructureMap 感到非常厌倦,进行了许多更改并且没有文档,我已经阅读了源代码,但是……为我的目标付出了太多的努力……

如果有人能给我一点光,我将不胜感激。

提前致谢。

另外......我在这里发布我的助手的真实代码以生成表达式树并注册插件系列:
public static class RegistrationHelper
{
public static void RegisterWithInterceptors(this Registry registry, Type interfaceToProxy, Type concreteType,
IInterceptor[] interceptors, ILifecycle lifecycle = null)
{
var proxyGenerator = new ProxyGenerator();

// Generate expression tree to call DecoreWith of StructureMap SmartInstance type
// registry.For<interfaceToProxy>().Use<concreteType>()
// .DecoreWith(ex => (IApplicationService)
// proxyGenerator.CreateInterfaceProxyWithTargetInterface(interfaceToProxy, ex, interceptors)
var expressionParameter = Expression.Parameter(interfaceToProxy, "ex");
var proxyGeneratorConstant = Expression.Constant(proxyGenerator);
var interfaceConstant = Expression.Constant(interfaceToProxy);
var interceptorConstant = Expression.Constant(interceptors);

var methodCallExpression = Expression.Call(proxyGeneratorConstant,
typeof (ProxyGenerator).GetMethods().First(
met => met.Name == "CreateInterfaceProxyWithTargetInterface"
&& !met.IsGenericMethod && met.GetParameters().Count() == 3),
interfaceConstant,
expressionParameter,
interceptorConstant);

var convert = Expression.Convert(methodCallExpression, interfaceToProxy);

var func = typeof(Func<,>).MakeGenericType(interfaceToProxy, interfaceToProxy);
var expr = Expression.Lambda(func, convert, expressionParameter);

// Register using reflection
registry.CallGenericMethod("For", interfaceToProxy, new[] {(object) lifecycle /*Lifecicle*/})
.CallGenericMethod("Use", concreteType)
.CallNoGenericMethod("DecorateWith", expr);
}
}
public static class CallMethodExtensions
{
/// <summary>
/// Call a method with Generic parameter by reflection (obj.methodName[genericType](parameters)
/// </summary>
/// <returns></returns>
public static object CallGenericMethod(this object obj, string methodName, Type genericType, params object[] parameters)
{
var metod = obj.GetType().GetMethods().First(m => m.Name == methodName && m.IsGenericMethod);
var genericMethod = metod.MakeGenericMethod(genericType);
return genericMethod.Invoke(obj, parameters);
}

/// <summary>
/// Call a method without Generic parameter by reflection (obj.methodName(parameters)
/// </summary>
/// <returns></returns>
public static object CallNoGenericMethod(this object obj, string methodName, params object[] parameters)
{
var method = obj.GetType().GetMethods().First(m => m.Name == methodName && !m.IsGenericMethod);
return method.Invoke(obj, parameters);
}

}

最佳答案

差不多两年后,我需要将这个问题归还给一个新项目。这次我已经解决了这次我使用了 StructureMap 4。

您可以使用自定义拦截器策略来装饰其类型的函数中的实例。您必须实现一个拦截器、一个拦截器策略并在注册表上对其进行配置。

拦截器

public class MyExInterceptor : Castle.DynamicProxy.IInterceptor
{
public void Intercept(Castle.DynamicProxy.IInvocation invocation)
{
Console.WriteLine("-- Call to " + invocation.Method);
invocation.Proceed();
}
}

拦截器策略
public class CustomInterception : IInterceptorPolicy
{
public string Description
{
get { return "good interception policy"; }
}

public IEnumerable<IInterceptor> DetermineInterceptors(Type pluginType, Instance instance)
{
if (pluginType == typeof(IAppService))
{
// DecoratorInterceptor is the simple case of wrapping one type with another
// concrete type that takes the first as a dependency
yield return new FuncInterceptor<IAppService>(i =>
(IAppService)
DynamicProxyHelper.CreateInterfaceProxyWithTargetInterface(typeof(IAppService), i));
}
}
}

配置
var container = new Container(_ =>
{
_.Policies.Interceptors(new CustomInterception());

_.For<IAppService>().Use<AppServiceImplementation>();
});

var service = container.GetInstance<IAppService>();
service.DoWork();

你可以得到一个关于这个要点的工作示例 https://gist.github.com/tolemac/3e31b44b7fc7d0b49c6547018f332d68 ,在gist中你可以找到三种装饰,第三种就是这样的答案。

使用它,您可以轻松配置服务的装饰器。

关于structuremap - 在约定中使用 CaSTLe DynamicProxy 和 StructureMap 3 进行装饰 - DecorateAllWith,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26414988/

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