ipjohnson / Grace

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

Question about export conditions #102

Closed darkcamper closed 7 years ago

darkcamper commented 7 years ago

Hi @ipjohnson

Is it possible to export something so that it has effect when the activation happens inside a certain scope (or nested scope) ?

I'm looking for something like this:

exportRegBlock
    .Export<AClass>()
    .As<AnInterface>()
    .When.InNamedScope(SCOPE_NAME)
    .Lifestyle.SingletonPerNamedScope(SCOPENAME);

I have two exports for the same type that should be SingletonPerNamedScope, but with different scope names and I'm getting NamedScopeLocateException when activating. I don't know in compile time which class will receive the injection (so I can't use When.XXXX).

Any ideas? Thanks!

ipjohnson commented 7 years ago

Hi @darkcamper

Out of the box Grace doesn't support request time conditions. It's something I've thought about before but it's pretty complicated and not very performant.

That said you can simulate what you want to do with a little bit of code yourself. I've put together a quick unit test showing how to use keys and a factory to achieve picking two different types based on a request time value (i.e. scope name)

ipjohnson commented 7 years ago

The other option you have is you can skip the keys and Locate the types directly (this is faster at the expense of writing a little more code)

container.Configure(c =>
{
    c.Export<BasicService>();
    c.Export<CustomBasicService>();
    c.ExportFactory<IExportLocatorScope, IBasicService>(
                    scope => scope.ScopeName == "CustomScope" ? 
                                     scope.Locate<BasicService>() : 
                                     scope.Locate<CustomBasicService();
});
darkcamper commented 7 years ago

I finally went with the AsKeyed + Factory method option you portrayed in the unit test, as I think it's more versatile and suits my needs better.

I agree with you that choosing the activation strategy using runtime information could be less performant but it would make the export api far more powerful and straightforward in some cases. Maybe sometime in the future as an optional feature?

Thank you for your quick response!