JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
563 stars 118 forks source link

Is it possible to intercept instances before they are returned so it is possible to wrap them without doing manual registry configurations for every type? #279

Closed Cybrosys closed 2 years ago

Cybrosys commented 3 years ago

Hello,

I was wondering if it is possible to intercept an instance right before it is returned? The reason why I am asking is that I am trying to add DynamicProxy around instances for trace logging and other tasks. The type of interface and implementation should not matter. I just want to intercept everything before it is returned.

I have been able to implement a Policy which intercepts Ctor arguments and wraps those, but the issue with that solution is that the instance requested won't be wrapped, only the dependencies it needs.

Update: Seems IDecoratorPolicy is what I am after.

In the TryWrap method, I am setting the "out Instance wrapped" to a LambdaInstance. The LambdaInstance is going to create my decorator/DynamicProxy, but it wants the instance that would have been created from "Instance inner".

I see that the LambdaFactory's IServiceProvider is the Lamar.Container, which can then be sent in to "inner.Resolve(...)" to get an instance. Would this be the "correct" way of doing it?

Update 2: It seems that my code for creating the instance is slow inside the LambdaInstance. What I'm doing is: var instance = inner.Resolve(container);

I've had that throw an exception depending on if an object has certain interfaces in the ctor. So if an exception is thrown I do this: instance = serviceProvider.GetService(inner.ImplementationType);

Update 3: I looked at the pull request for "Activation interceptor" and created an ActivationInterceptor which generates the DynamicProxy on the instance returned. This results in the performance being back to normal. You should approve the PR and merge it.

jeremydmiller commented 2 years ago

Closed with the new interception features in v6. See https://jasperfx.github.io/lamar/guide/ioc/decorators.html

rizi commented 2 years ago

@Cybrosys would you mind sharing your solution with me, I think I tried to achieve the same, may you have a look at: https://github.com/JasperFx/lamar/issues/310

Cybrosys commented 2 years ago

@Cybrosys would you mind sharing your solution with me, I think I tried to achieve the same, may you have a look at: #310

Of course, but it'll have to wait a day or two as it's Christmas, I'll let you know once I've created a simple sample for you.

rizi commented 2 years ago

@Cybrosys would you mind sharing your solution with me, I think I tried to achieve the same, may you have a look at: #310

Of course, but it'll have to wait a day or two as it's Christmas, I'll let you know once I've created a simple sample for you.

Of course, take your time and enjoy your christmas feast! Just to let you know, maybe a sample is not needed, just have a look at my solution (I posted a link above) maybe it's quite similar and you just have to give me some tips. Br

Cybrosys commented 2 years ago

@Cybrosys would you mind sharing your solution with me, I think I tried to achieve the same, may you have a look at: #310

Of course, but it'll have to wait a day or two as it's Christmas, I'll let you know once I've created a simple sample for you.

Of course, take your time and enjoy your christmas feast! Just to let you know, maybe a sample is not needed, just have a look at my solution (I posted a link above) maybe it's quite similar and you just have to give me some tips. Br

Here's a repo with a console app sample: https://github.com/Cybrosys/LamarCastleSample

Start by checking out Registry.cs. A decorator policy is used to determine if something should be wrapped or not (passing in a func). I use Castle.Core to generate a dynamic proxy around the object passing in the interceptors I want to be invoked; in this case it's a simple "BeforeAfterInterceptor" which just outputs Before and After to the console.

I tell Lamar to give me an instance of IRandomService and then I invoke the method from that interface, the output is: Before Random number After

rizi commented 2 years ago

@Cybrosys would you mind sharing your solution with me, I think I tried to achieve the same, may you have a look at: #310

Of course, but it'll have to wait a day or two as it's Christmas, I'll let you know once I've created a simple sample for you.

Of course, take your time and enjoy your christmas feast! Just to let you know, maybe a sample is not needed, just have a look at my solution (I posted a link above) maybe it's quite similar and you just have to give me some tips. Br

Here's a repo with a console app sample: https://github.com/Cybrosys/LamarCastleSample

Start by checking out Registry.cs. A decorator policy is used to determine if something should be wrapped or not (passing in a func). I use Castle.Core to generate a dynamic proxy around the object passing in the interceptors I want to be invoked; in this case it's a simple "BeforeAfterInterceptor" which just outputs Before and After to the console.

I tell Lamar to give me an instance of IRandomService and then I invoke the method from that interface, the output is: Before Random number After

Thank you very much for the detailed information and the included sample.

Br