Decoration using Castle DynamicProxy and StructureMap 3 in convention - DecorateAllWith

How to use DecorateAllWith to decorate with DynamicProxy all instances implement the interface?

For instance:

 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 ...?? } } } 

I could decorate some interfaces for specific types using (for example):

 var proxyGenerator = new ProxyGenerator(); registry.For<IApplicationService>().Use<BaseAppService>().DecorateWith(service => proxyGenerator.CreateInterfaceProxyWithTargetInterface(....)) 

But havent been able to use DecorateAll for this.

To call registry.For<>().Use<>().DecorateWith() , I have to do this:

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

Only for crazy minds ...

I'm starting to get very tired of StructureMap, a lot of changes and no documentation, I read the source code, but ... too much effort for my purpose ...

If someone can give me some light, I will be grateful.

Thanks in advance.

Also ... I am posting here my real helper code to generate an expression tree to register the plugin family:

 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); } } 
+5
source share
1 answer

Almost two years later, I needed to bring this issue back for a new project. This time I decided that this time I used StructureMap 4.

You can use a custom interceptor policy to decorate an instance in a function of its type. You must implement one interceptor, one interceptor policy and configure it in the registry.

Interceptor

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

Interceptor policy

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

Configuration

 var container = new Container(_ => { _.Policies.Interceptors(new CustomInterception()); _.For<IAppService>().Use<AppServiceImplementation>(); }); var service = container.GetInstance<IAppService>(); service.DoWork(); 

You can get a working example from this gist https://gist.github.com/tolemac/3e31b44b7fc7d0b49c6547018f332d68 , in essence you can find three types of decorations, the third - like this answer.

Using it, you can easily customize the decorators of your services.

+3
source

Source: https://habr.com/ru/post/1204874/


All Articles