开发者

Depencency injection question

开发者 https://www.devze.com 2023-01-23 11:09 出处:网络
I have a question regarding dependency injection pattern. My question is... If I go for constructor injection, injecting the dependencies for my class, what I get is a \"big\" constructor with many pa

I have a question regarding dependency injection pattern. My question is... If I go for constructor injection, injecting the dependencies for my class, what I get is a "big" constructor with many params. What if ie. I dont use some of the params in some methods? Ie. I have a service that exposes many methods. And a constructor with 10 parameters (all dependencies). But not all the methods uses all the dependencies. Some method will use only one dependency, another will use 3 dependencies. But DI container will resolve them all even if non are used.

To me this is a performance penalty of usi开发者_Python百科ng DI container. Is this true?


It seems your class is doing to much, that it does not comply to the S in SOLID (Single responsibility principle) , maybe you could split the class in multiple smaller classes with less dependencies. The fact that not all dependencies are used by all methods suggests this.


Normally the performance penalty of injecting many dependencies is low, but it depends on the framework you pick. Some will compile methods for this on the fly. You will have to test this. Many dependencies does indicate that your class is doing too much (like Ruben said), so you might want to take a look at that. If creation of an instance of a depedency that you often don't use causes performance problems, you might want to introduce a factory as dependency. I found that the use of factories can solve many problems regarding the use of dependency injection frameworks.

// Constructor
public Consumer(IContextFactory contextFactory)
{
    this.contextFactory = contextFactory;
}

public void DoSomething()
{
    var context = this.contextFactory.CreateNew();
    try
    {
        // use context here

        context.Commit();
    }
    finally
    {
        context.Dispose();
    }
}


You can also hide some not-yet-needed dependencies behind lazy providers. For instance:

public DataSourceProvider implements Provider<DataSource> {

    public DataSource get() {
         return lazyGetDataSource();
    }

}

The Provider interface is part of javax.inject package.


Actually you can't know which methods are used at runtime when you build your DI container. You would have to deal with that performance penalty or if you know that there are many cases where just a few dependencies are used, you could split your container into several small containers that have less dependencies that are injected.


As rube Says probabily you should review te design of your class to stick to SOLID principles.

Anyway if it is not really necessary I'm used to go for property setter dependency insteadof the constructor. It means that you can create a property for each dependecy you need. That helps also to test the class because you can inject only the dependency you need into the context of the test you are doing instead of stub out all the dependency even if you don't need it

0

精彩评论

暂无评论...
验证码 换一张
取 消