ipjohnson / Grace

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

ExportDecorator with When.InjectedInto won't fire #192

Closed mgth closed 5 years ago

mgth commented 5 years ago

If i do not put the condition Decorator is applied, but when When.InjectedInto is used the decorator is never applied. I'm using a Func<param, IService> in the constructor. Doing this with standard export works as expected but not with decorator.

ipjohnson commented 5 years ago

@mgth I was able to replicate the bug. I'll see if I can fix it this weekend at some point and do a beta release.

ipjohnson commented 5 years ago

@mgth I've released a pre-release version to nuget. Can you test it out?

mgth commented 5 years ago

Sorry, it still fail for me. But this is special case where I must use Container.Inject(obj); Another thing is the decorator itself does not get injected.

ipjohnson commented 5 years ago

@mgth you’ll need to put together a sample showing the issue.

mgth commented 5 years ago
    interface IService { }
    class MyService : IService { }
    class MyServiceDecorator : IService { }

    interface IMyClass { }
    class MyClass : IMyClass
    {
        [Import]
        public Func<IService> GetService { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var container = new DependencyInjectionContainer();

            container.Configure( c =>
            {
                c.Export<MyClass>().As<IMyClass>().ImportMembers();
                c.Export<MyService>().As<IService>();
                c.ExportDecorator(typeof(MyServiceDecorator)).As(typeof(IService)).When.InjectedInto<IMyClass>();
            });

            var myClass = new MyClass();
            container.Inject(myClass);

            // there getService will return a MyService when it should return a MyServiceDecorator
            var service = myClass.GetService();
        }
    }

when this will return a MyServiceDecorator as expected var myClass = (MyClass)container.Locate<IMyClass>();

ipjohnson commented 5 years ago

@mgth the reason it's not work the way you want it to is because the Inject method is an extension and isn't a first class feature in the container. No strategy is created for an injected type so the default implementation for WhenInjectedInto won't work.

I'm not inclined to make a change to the default behavior because it could have unintended side effects but you could do a custom condition like this.

mgth commented 5 years ago

Ok, that works. Thank you much for your precious time.

ipjohnson commented 5 years ago

@mgth glad I was able to address your issue. I'm going to close this as fixed, if you run into anything more open an issue and I'll try and address it.

I'll plan on doing an official release near the end of this month.