ipjohnson / Grace

Grace is a feature rich dependency injection container library
MIT License
337 stars 33 forks source link

Resolve request interceptor (smth like UnityContainerExtension / BuilderStrategy in Unity) #82

Closed ILAgent closed 7 years ago

ILAgent commented 7 years ago

It is necessary for me to have availability of service resolving interception. Sorry, if it already is, please show how to achieve. Thank you !

ipjohnson commented 7 years ago

@ILAgent I'm not familiar with unity's BuilderStrategy, do you have some documentation you can point me at so I can better understand the feature.

At this point Grace supports the decorator pattern that some people use for interception. Here are some of the unit test where I'm using Castle Core for interception (Note: the Interception extension is not part of Grace it's found here

As interception is a pretty large topic some specifics might help. Are you doing your own interception or using a library like Castle Core?

ILAgent commented 7 years ago

Thank you, I've seen. But I'd like to intercept pre and post build moments for all services in my container. In Unity I can do it such:


 public class MyExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            Context.Strategies.Add(new MyStrategy(), UnityBuildStage.PreCreation);
        }

        private class MyStrategy : BuilderStrategy
        {
            public override void PostBuildUp(IBuilderContext context)
            {
            }

            public override void PreBuildUp(IBuilderContext context)
            {
            }
        }
    }

Also example is here http://mark-dot-net.blogspot.ru/2009/09/custom-object-factory-unity-extension.html

I haven't understood, how to implement it with Grace.

ipjohnson commented 7 years ago

@ILAgent I'm going to be honest with you Grace wasn't built with this type of use case in mind because it's really slow to execute at request time.

Grace essentially builds delegates on the fly that look something like this

private object CreationDelegateForSomeClass(scope, disposalScope, injectionContext)
{
  return new SomeClass(new SomeDependency(), new SomeOtherDependency); 
}

Grace supports the idea of post build up with decorators but no PreBuildUp. With some work you can probably mimic the behaviors you're looking for but it's not out of the box. For example the article you linked to talks about using it for caching where as in Grace you'd just create your own lifestyle that implements caching.

Out of curiosity what is it you do with the pre and post that's the same for all objects? Some type of logging?

ILAgent commented 7 years ago

Yes, I have to log resloving time for each service, so I need to measure intervals between pre and post build moments. Is it possible with Grace ?

ipjohnson commented 7 years ago

@ILAgent sorry it's not really possible at this point in time, that said with the way top performing containers (Grace, DryIoc, lightinject, etc) are written you're going to spend far more time trying to time the instantiation than it takes to actually instantiate the object.

Performance numbers show that

I'm not saying Grace is for you or that it will solve all your issues but instantiation performance is probably not one of the problems you will have with Grace

ipjohnson commented 7 years ago

Sorry I did the math wrong untity for the complex use case is 450x slower than grace.

ILAgent commented 7 years ago

Thank you, perfomance is general reason why I'm looking to Grace. But unfortunately my services have complex constructors and must be profiled...

ipjohnson commented 7 years ago

@ILAgent it's possible to time a whole object graph being constructed but at this point I don't really see a good way to add the feature on a per instatiation basis and keep things performant.

Wish I had a better answer for you but part of the reason Grace is as fast as it is, is because it's not quite as dynamic as Untity and NInject (No pre-build up only post).

ipjohnson commented 7 years ago

@ILAgent I thought about it some more and maybe there is a way to do what you are looking to do. I've refactored the constructor logic recently for issue #78 and I think maybe something like this could work for your situation

Custom constructor logic

I'd consider formalizing it if it works for you.

ipjohnson commented 7 years ago

@ILAgent were you able to get this solution working or have you moved onto another container?

ILAgent commented 7 years ago

Hi ! I've found too difficult to change ioc container in my project, that's why I have not tried yet.

ipjohnson commented 7 years ago

Completely understand. Depending on how it's built it's like trying to replace your house's foundation while still living in it.

I think for moment I'm going to close this issue, then in a couple months when I have some more time I'll open a new issue for implementing this feature as it does seem interesting just not something I can implement now (I official have less than 5 weeks to finish some pressing issues before the new born arrives)

ILAgent commented 7 years ago

Thank you ! Hope I'll try Grace in the nearest future.