Pregunta

I want to inject Container property via SimpleInjector. I didn't find any functionality of SimpleInjector for that.

Then I wanted to register self container to itself, but Container has no interface.

I want this functionality because I don't to transfer Container object via constructor - because why if I can use auto inject of register objects.

My usage idea:

var container = new Container();
container.Options.AutowirePropertiesWithAttribute<InjectableProperty>();
container.Register<ISomething, Something>(Lifestyle.Singleton);

ISomething:

public interface ISomething 
{
   void SomeMethod();
}

Something class:

public class Something : ISomething 
{
    public void SomeMethod() 
    {
       var environment = _container.GetInstance<IEnvironment>();
       environment.DoSomething();
    }

    [InjectableProperty] // - maybe it is not possible (I don't know it)
    Container Container {get;set;}
}

Do you have any idea to achieve that?

Thank you very much.

¿Fue útil?

Solución

Prevent having your application code depend upon the container. The only place in your application that should know about the existence of your DI library is the Composition Root (the place where you register all your dependencies).

Instead of letting each class call back into the container (which is called the Service Locator anti-pattern), prefer using Dependency Injection. With Dependency Injection you inject dependencies instead of asking for them.

So you can rewrite your class to the following:

public class Something : ISomething 
{
    private readonly IEnvironment environment;

    public Something (IEnvironment environment)
    {
       this.environment = environment;
    }

    public void SomeMethod()
    {
       this.environment.DoSomething();
    }
}

Also, prevent doing any logic in your constructors besides storing the incoming dependencies. This allows you to compose object graphs with confidence.

In some cases however, it can still be useful to inject the Container into another class. For instance when creating a factory class that is located inside the Composition Root. In that case you can still use constructor injection, like this:

// Defined in an application layer
public interface IMyFactory
{
    IMyService CreateService();
}

// Defined inside the Composition Root
public class MyFactory : IMyFactory
{
    private readonly Container container;

    public MyFactory(Containter container)
    {
        this.container = container;
    }

    public IMyService CreateService(ServiceType type)
    {
        return type == ServiceType.A
            ? this.container.GetInstance<MyServiceA>()
            : this.container.GetInstance<MyServiceB>();
    }
}

If Simple Injector detects a Container constructor argument, it will inject itself into the constructor automatically.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top