ipjohnson / Grace

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

Type Activator For Decorator, Does Not Invoke Dependency's Factory if It Has Conditions #279

Open falamarzijahromi opened 3 years ago

falamarzijahromi commented 3 years ago

I'm trying to use the decorator feature with ctor param by using Castle Dynamic Proxy for generating dynamic proxy types as decorators for using them as interceptors. When I Export the dependency by factory under any conditions , it doesn't work. But there's no problem if the dependency does not have any conditions.

` block .ExportDecorator(decoratorType) .As(tServiceType) .WithCtorParam<GenericCastleInterceptor, IInterceptor[]>(i => new IInterceptor[] { i });

      block
            .ExportFactory<IServiceProvider, GenericCastleInterceptor>(sp =>
            {
                return new GenericCastleInterceptor(applicationInterceptorsTypes, sp);
            })
            .As<GenericCastleInterceptor>()
            .When.InjectedInto(type =>
            {
                return true;
            })
            .When.MeetsCondition((strategy, context) =>
            {
                return true;
            });

`

or

` block .ExportDecorator(decoratorType) .As(tServiceType) .WithCtorParam<GenericCastleInterceptor, IInterceptor[]>(i => new IInterceptor[] { i });

      block
            .ExportFactory<IServiceProvider, GenericCastleInterceptor>(sp =>
            {
                return new GenericCastleInterceptor(applicationInterceptorsTypes, sp);
            })
            .As<GenericCastleInterceptor>()
            .When.InjectedInto(decoratorType);

`

The above code snippets do not work whether using InjectedInto or hacking with MeetsCondition to make conditions for exporting. But the code snippet below works well.

` block .ExportDecorator(decoratorType) .As(tServiceType) .WithCtorParam<GenericCastleInterceptor, IInterceptor[]>(i => new IInterceptor[] { i });

      block
            .ExportFactory<IServiceProvider, GenericCastleInterceptor>(sp =>
            {
                return new GenericCastleInterceptor(applicationInterceptorsTypes, sp);
            })
            .As<GenericCastleInterceptor>();

`

ipjohnson commented 3 years ago

Hi @falamarzijahromi

When you use just the MeetsCondition method is the method being called to test if it meets the condition? If so can you look at the static injection information and look to see what types it's being injected into?

I'm not able to replicate the problem but I also don't have the same sets of dependencies so I'm not sure what's going on.

falamarzijahromi commented 3 years ago

Hi @ipjohnson Thanks for your Quick response. I've submitted a PR to replicate the problem by test: https://github.com/ipjohnson/Grace/pull/280

I think the problem is StaticInjectionContext doesn't have any information about the dependent object which is activating the dependency for. Therefor InjectedInto's test does not invoke during activation. I've also added a test which shows MeetsCondtion method is called to test the condition.

ipjohnson commented 3 years ago

Hi @falamarzijahromi

Decorated classes never know they are being decorated and the information isn't passed onto the conditional logic. The examples you gave aren't injecting into anything so the injected into information is going to be blank.

falamarzijahromi commented 3 years ago

Hi @ipjohnson

Sounds reasonable for the layers of abstraction in the operational code. But is it ok for injecting contexts too?

Practically, the service is going to be decorated will be injected into the decorator. By having this point of view, behaving decoration is some like injection, Therefore injecting interfaces should work there too.

ipjohnson commented 3 years ago

Hi @falamarzijahromi

I understand where you're coming from but ultimately it's not how it was implemented. Currently when a dependency is located we find a registration that matches and then decorate it. So the conditional logic for selecting a dependency is run then decorators are applied.