ipjohnson / Grace

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

Specific key with WithCtorParam #268

Open silkfire opened 3 years ago

silkfire commented 3 years ago

When using the WithCtorParam method with a single argument and in need to resolve a dependency with specific key, I know that you can use LocateWithKey like this:

_.Export<Service>().WithCtorParam<IDependency>().LocateWithKey("key")
 .As<IService>();

But how do you solve this with multiple dependency arguments?

_.Export<Service>().WithCtorParam<ISubDependecy1, ISubDependency2, IDependency>((sd1, sd2) => new Dependency(sd1, sd2))
 .As<IService>();

ISubDependecy1 and ISubDependency2 are previously registered and with different keys.

ipjohnson commented 3 years ago

I think at the moment there isn't really a way to handle. This maybe a case where you have to hand wire this instance. I'll look at what it would take to do something like WithCtorParam<T>(Func<IExportLocatorScope,T> func) where you can wire up the specific logic you need for wiring up the dependency,

silkfire commented 3 years ago

Thanks, that sounds like a good solution. Perhaps an exception should be thrown if you use the multi-type methods and then LocateWithKey as the behavior would be undefined?

_.Export<Service>().WithCtorParam<ISubDependecy1, ISubDependency2, IDependency>((sd1, sd2) => new Dependency(sd1, sd2)).LocateWithKey("key")    // Throws no error, but which dependency are we referring to?
 .As<IService>();

I've got a separate key-related question so I'll just cheekily ask it here. I'm registering a dependency by key. In my controller I have that dependency in the constructor, without any [Import] attribute. But I'm getting an exception that Grace can't resolve the dependency. I thought it should just try to pick the last registered dependency that matches the type, ignoring the key?

ipjohnson commented 3 years ago

Hmm that's tough the container isn't going to resolve that because you specifically registered the dependency with a key and the controller constructor has no way to decided which dependency to use.

You should be able to put an [Import(key = "SomeKey")] on the parameter and that should allow you to specify the key.

silkfire commented 3 years ago

I'm not a big fan of the [Import] attribute tbh. Would it be possible to enable this kind of functionality through a flag? Eg. AutoResolveKeyedRegistrations. This will pick the last registration based on type, ignoring any keys.

ipjohnson commented 3 years ago

Honestly I'm not a huge fan either but I also don't do keyed registration either. I think it could be an option to have a flag like that but I probably can't implement it any time soon. What if you exported a non keyed version that just looks up the keyed version you want?

silkfire commented 3 years ago

I suppose I could do that, yeah. Thanks for the tip!