它是不好用servicelocation而不是构造函数注入,以避免工厂类的写作负荷 [英] Is it bad to use servicelocation instead of constructor injection to avoid writing loads of factory classes

查看:243
本文介绍了它是不好用servicelocation而不是构造函数注入,以避免工厂类的写作负荷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我们使用DI / IOC,当我们需要额外的参数传递给我们使用工厂类的构造函数例如。

 公共类EmailSender
{
    内部EmailSender(字符串toEmail,串主题,绳体,ILogger emailLogger)
    {} .....
}公共类EmailSenderFactory
{
    ILogger emailLogger;
    公共EmailSenderFactory(ILogger emailLogger)
    {
        this.emailLogger = emailLogger;
    }
    公共EmailSender创建(字符串toEmail,弦乐主题,绳体)
    {
        返回新EmailSender(toEmail,主题,正文,emailLogger);
    }
}

现在这个问题是我们最终建立一个整体洛塔工厂类,人们总是不知道使用它们(他们有时新起来自理)。什么是编码类这样的最大劣势:

 公共类EmailSender
{
    EmailLogger记录= IoC.Resolve< ILogger>();
    内部EmailSender(字符串toEmail,串主题,绳体)
    {} .....
}

临:我们现在可以放心地使用构造而无需工厂类
缺点:我们必须引用了服务定位器(我并不担心可测试性,其易于使用的模拟容器为容器支撑服务)

是否有一个原因,一些大的臭气熏天在那里,为什么我们不应该这样做?

编辑:经过一番考虑,我突然意识到通过具有私有的构造,并通过嵌套工厂类,我可以继续实施和工厂一起,从不当创建类prevent人,所以这个问题已经变得有些没有实际意义。所有关于SL是脏点分,当然是真实的,所以下面的解决方案,让我开心:

 公共类EmailSender
{
    公共类厂
    {
        ILogger emailLogger;
        众厂家(ILogger emailLogger)
        {
            this.emailLogger = emailLogger;
        }
        公共EmailSender创建(字符串toEmail,弦乐主题,绳体)
        {
            返回新EmailSender(toEmail,主题,正文,emailLogger);
        }
    }
    私人EmailSender(字符串toEmail,串主题,绳体,ILogger emailLogger)
    {
    }
}


解决方案

是 - 它是坏的。


  • 为什么写所有code时,你可以有框架做的工作?所有IoC.Resolve()调用是
    多余的,你不应该
    写他们。

  • 另一个更重要的方面,
    那是你的组件是绑
    您的服务定位器。

    您现在已经无法实例化它们
    就是这样 - 你需要一个
    完全建立在服务定位器
    把每一次你需要使用一个
    组件。


  • 最后,机器人至少有 - 你的SL code是
    洒在你的codeBase类
    这是不是一件好事,因为
    当你想改变一些东西,
    您在多个地方寻找。

Right now we use DI/IOC and when we need to pass extra parameters to a constructor we use a factory class e.g.

public class EmailSender 
{
    internal EmailSender(string toEmail, string subject,String body, ILogger emailLogger)
    {.....} 
}

public class EmailSenderFactory
{
    ILogger emailLogger;
    public EmailSenderFactory(ILogger emailLogger)
    { 
        this.emailLogger = emailLogger;
    }
    public EmailSender Create(string toEmail, string subject, string body) 
    {
        return new EmailSender(toEmail, subject, body, emailLogger);
    }
}

Now the problem with this is that we end up creating a whole lotta factory classes, and people don't always know to use them (they sometimes new them up themselves). What are the biggest negatives of coding the class like this:

public class EmailSender 
{
    EmailLogger logger = IoC.Resolve<ILogger>();
    internal EmailSender(string toEmail, string subject,String body)
    {.....} 
}

Pro: we now can use the constructor safely without needing a factory class Con: we have to reference the Service Locator (I'm not worried about testability, its easy to use a mock container as the backing service for the container).

Is there some big stinker of a reason out there why we shouldn't do this?

edit: after a bit of thought, I twigged that by having a private constructor, and by nesting the Factory class, I could keep the implementation and factory together, and prevent people from creating classes improperly, so the question has become somewhat moot. All the points points about SL being dirty, are of course true, so the solution below keeps me happy:

public class EmailSender 
{
    public class Factory
    {
        ILogger emailLogger;
        public Factory(ILogger emailLogger)
        { 
            this.emailLogger = emailLogger;
        }
        public EmailSender Create(string toEmail, string subject, string body) 
        {
            return new EmailSender(toEmail, subject, body, emailLogger);
        }
    }
    private EmailSender(string toEmail, string subject,String body, ILogger emailLogger)
    {
    } 
}

解决方案

yes - it is bad.

  • Why write all that code when you can have the framework do the work? All the IoC.Resolve() calls are superfluous and you shouldn't have to write them.
  • Another, even more important aspect, is that your components are tied to your service locator.

    You're now unable to instantiate them just like that - you need a completely set up service locator in place every time you need to use a component.

  • Last but, bot least - your SL code is sprinkled all over your codebase which is not a good thing, because when you want to change something, you have to look in multiple places.

这篇关于它是不好用servicelocation而不是构造函数注入,以避免工厂类的写作负荷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆