c# - IoC 对我的工厂单例的好处

标签 c# singleton inversion-of-control

在 SO 上似乎存在关于使用单例的耻辱。我个人从来没有买过它,但出于开放的心态,我正在尝试尝试 IoC 概念作为替代方案,因为坦率地说,我对我的日常工作感到厌倦,并且想尝试一些不同的东西。如果我对 IoC 概念的解释不正确或有误,请原谅我。

情况是这样的:我正在构建一个简单的 HttpListener基于 Windows 服务中的 Web 服务器,它利用插件模型来确定应如何根据请求的 URL 处理请求(就像其他询问 HttpListener 的人一样)。我发现插件的方法是查询已配置的目录以查找装饰有 HttpModuleAssemblyAttribute 的程序集。 .这些程序集可以包含 0 个或多个 IHttpModule另外装饰有HttpModuleAttribute的 child 用于指定模块的名称、版本、人类可读的描述和各种其他信息。像这样的东西:

[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : IHttpModule
{
    public void Execute(HttpListenerContext context)
    {
        /* Do Something Special */
    }
}

HttpModule被发现我通常会将其添加到 Dictionary<string, Type> object who 的唯一目的是跟踪我们知道的模块。这本词典通常会存在于我的单例的变体中,它呈现出一个 ACE style Singleton 的角色。 (这是我学习单例的 C++ 时代留下的遗产)。

现在我正在尝试实现的是使用(我对)一般 IoC 概念的类似内容。基本上我有一个 AppService收藏地点IAppService定义为:

public interface IAppService : IDisposable
{
    void Initialize();
}

还有我的插件AppService看起来像:

[AppService("Plugins")]
internal class PluginAppService : IAppService, IDictionary<string, Type>
{
    /* Common IDictionary Implementation consisting of something like: */
    internal Type Item(string modName)
    {
        Type modType;
        if (!this.TryGetValue(modName, out modType)
            return null;

        return modType;
    }

    internal void Initialize()
    {
        // Find internal and external plug-ins and add them to myself
    }

    // IDisposable clean up method that attempts to dispose all known plug-ins
}

然后在服务期间OnStart我实例化了一个 AppServices 的实例这是本地已知的,但传递给所有实例化插件的构造函数:

public class AppServices : IDisposable, IDictionary<string, IAppService>
{
    /* Simple implementation of IDictionary */

    public void Initialization()
    {
        // Find internal IAppService implementations, instantiate them (passing this as a constructor parameter), initialize them and add them to this.

        // Somewhere in there would be something like
        Add(appSvcName, appSvc);
    }
}

我们曾经的单一方法实现变成了抽象实现 + 子构造器:

[HttpModule(/*Some property values that matter */)]
public abstract class HttpModule : IHttpModule
{
    protected AppServices appServices = null;
    public HttpModule(AppServices services)
    {
        appServices = services;
    }            

    public abstract void Execute(HttpListenerContext context);
}

[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : HttpModule
{
    public SimpleHttpModule(AppServices services) : base(services) { }
    public override void Execute(HttpListenerContext context)
    {
        /* Do Something Special */
    }
}

并且对常用应用程序服务的任何访问都变成:

var plugType = appServices["Plugins"][plugName];

而不是:

var plugType = PluginManager.Instance[plugName];

我是否遗漏了一些可以简化这一切的基本 IoC 概念,或者所有这些额外的代码真的有好处吗?在我的世界中,单例是简单的生物,允许整个程序中的代码访问所需的(相对静态的)信息(在本例中为类型)。

更明确地提出问题:

  1. 这是转换为 IoC/DI 概念的 Factory Singleton 的有效实现吗?
  2. 如果是,那么需要额外代码和强加看似更笨重的 API 的返回/好处在哪里?

最佳答案

IoC 是一个通用术语。依赖注入(inject)是当今更受欢迎的术语。

依赖注入(inject)在某些情况下确实很出色。首先,它定义了一个比具有硬编码依赖实例的解决方案更可测试的架构。单例很难进行单元测试,因为它们是静态的,静态数据无法“卸载”。

其次,Dependency Injection不仅仅实例化你想要的类型,而是所有的依赖类型。因此,如果 A 类需要 B 类,B 类需要 C 类和 D 类,那么一个好的 DI 框架将自动创建所有依赖项,并控制它们的生命周期(例如,使它们在单个 Web 请求的生命周期内存在)。

DI 容器可以被认为是可以实例化任何类型对象的通用工厂(只要它被正确配置并满足 DI 框架的要求)。所以你不必编写自定义工厂。

与任何通用解决方案一样,它旨在为 90% 的用例提供他们需要的东西。当然,您可以在每次需要集合时创建一个手工制作的自定义链表数据结构,但 90=% 的时间一个通用的就可以正常工作。 DI 和自定义工厂也是如此。

关于c# - IoC 对我的工厂单例的好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9074155/

相关文章:

javascript - 是否保证在 webpack 或 rollup 模块打包过程中保留单例?

java - 以编程方式将 DirectChannelMetrics 注册为 JMX Bean

c# - 如何从对象数据源获取数据集列值

java - spring 中的单例可以有静态方法吗?

c# - VS2012 中的 Windows Phone 8 SDK,图标?

iOS swift单例清除数据

dependency-injection - 什么是理解 IoC 和 DI 的好类比?

java - Guice:如何根据(动态网络属性)在运行时更改注入(inject)

c# - 尝试将变量从 C# 插入 MySQL 时出错

c# - 保存到数据库时验证数据字段是否太大?