ipjohnson / Grace

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

BUG wrong child container locate behavior #122

Closed mcdis closed 7 years ago

mcdis commented 7 years ago
var root = new DependencyInjectionContainer();
root.Configure(_ =>_.Export<FileLogListener>().AsKeyed<ILogListener>("file"));
var child = root.CreateChildScope(_ => _.ExportInstance<ILogListenerSettings>(new LogListenerSettings()));
var listener = child.Locate<ILogListener>("file");

FileLogListener depends on ILogListenerSettings So...exception: Grace.DependencyInjection.Exceptions.LocateException: Could not locate Type ILogListenerSettings

but child.Locate() resolve normally with normal ILogListenerSettings instance.

ipjohnson commented 7 years ago

try this

root.Configure(
     _ =>_.Export<FileLogListener>().AsKeyed<ILogListener>("file").WithCtorParam<ILogListenerSettings>().IsDynamic());
mcdis commented 7 years ago

That's work, but in common case there can be many dependencies inside "FileLogListener". So it would complicated to maitance the code becouse I've to duplcate depencdencies (in ctor and in registration). For me that's the base scenary...I create child container, throughout some bahaviors and resolve component. So during resolve the dependecies have to be resolved from child container. I've checked StructureMap for this functional and StrucutreMap fail.

And I've got another Issue: Add some constraints to methods like that:

ipjohnson commented 7 years ago

@mcdis if you want your default behavior to always be dynamic then you can change the constructor selection logic to be dynamic all the time with this.

var container = new DependencyInjectionContainer(c => c.Behaviors.ConstructorSelection = ConstructorSelectionMethod.Dynamic);

I'm not sure I follow the "Add Some constraints" comment. Could you elaborate?

mcdis commented 7 years ago

About constraints: exists code: c.Configure(_ =>_.Export<ConsoleLogListener>().AsKeyed<IApp>("console")); No errors (static checking) But ConsoleLogListener doesn't implement IApp at all. For example in Unity: public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, params InjectionMember[] injectionMembers) where TTo : TFrom The key: where TTo : TFrom So that's add static checking. At this moment I'm looking alternative to unity because no support/maintance. And when I've started use the Grace there was some simple error: I've used wrong call order: _=>_.Export<IInterface>().As<Impl>() but there was no error during code time. In Export<TTo>.As<TFrom> there no type constraint: where TTo:TFrom

mcdis commented 7 years ago

@ipjohnson thak you new DependencyInjectionContainer(c => c.Behaviors.ConstructorSelection = ConstructorSelectionMethod.Dynamic); That's work perfect.

ipjohnson commented 7 years ago

@mcdis there is a C# extensions similar to unity that has the constraints you want. It's just not possible with the Export<T> because of the way it's defined.

c.Configure(_ => _.ExportAs<TImpl, TInterface>());
mcdis commented 7 years ago

But you can add constraint to As<>

public interface IFluentExportStrategyConfiguration<T>
{
    IFluentExportStrategyConfiguration<T> As<TInterface>() where T:TInterface; // <--- where
}
mcdis commented 7 years ago

ExportAs - thank you. I didn't know