【问题标题】:Dependency Injection - Choose DLL and class implementation at runtime through configuration file依赖注入 - 通过配置文件在运行时选择 DLL 和类实现
【发布时间】:2011-06-16 08:37:17
【问题描述】:

我有一个 API DLL(例如 API.dll),除了许多其他想法之外,它还提供了一个抽象类(AbstractClass)。

现在利用那个 AbstractClass 我已经在两个不同的 dll 上实现了它:

  • First.API.Implementation.dllConcreteImplementation1
  • Second.API.Implementation.dllConcreteImplementation2

ConcreteImplementation1 和 ConcreteImplementation2 都是同一个抽象类的实现。

我想要的是一个应用程序,我可以在其中选择要使用这两个 dll 中的哪一个,并通过它选择要使用的实现,而无需用户更改代码中的任何内容,并且如果可能的话,无需停止应用程序。

一些配置文件,我可以让应用程序使用我想要的任何实现。比如:

<appconfiguration>
    <implementation_to_use>
        <dll>First.API.Implementation.dll</dll>
        <class>ConcreteImplementation1</class>
    </implementation_to_use>
</appconfiguration>

我对依赖注入几乎一无所知,除了它的概念,但我想那是完成这项任务的完美选择。

我研究了几个 DI/IoC 库,但我并不熟悉所有的概念和名称。我可以使用任何我想要的库。我可以说这些是最常用的:StructureMapNinjectSprint.NET

此外,除了所有 dll 和实现之外,我还需要指明该应用程序要使用的文件。我可以在同一个文件中指明它的路径吗?

我只需要一些提示和指导来实现这样的事情。使用其中一个库的一些示例会很棒。

谢谢。

【问题讨论】:

  • 你不能有两个不同的抽象基类,两个具体的实现必须派生自同一个抽象类。还是界面,比较常见的选择。然后只需使用 Activator.CreateInstance()。
  • 对不起。示例中使用的名称选择不当。 AbstractImplementation1 和 AbstractImplementation2 都是同一个抽象类的具体实现。我会修改名称。
  • 您仍然需要修复代码 sn-p。它必须包含具体类型的名称,而不是抽象类型的名称。
  • MEF 可能值得一看。

标签: c# dependency-injection inversion-of-control configuration-files


【解决方案1】:

要让您开始使用StructureMap,请创建一个控制台应用程序,并在其中包含:

结构图配置:

<?xml version="1.0" encoding="utf-8" ?>
<StructureMap MementoStyle="Attribute">
  <DefaultInstance
    PluginType="DemoIoC.AbstractBase,DemoIoC"
    PluggedType="DemoIoC.ConcreteImplementation1,DemoIoC"
    Scope="Singleton" />
</StructureMap>

PluginType 和 PluggedType 属性是“FullyQualifiedClassName,AssemblyName” 默认情况下,它将在可执行文件夹中查找程序集,我不确定您将如何为程序集指定另一个位置

Scope 有很多选项,例如单例、瞬态等

程序.cs:

namespace DemoIoC
{
    using System;
    using StructureMap;

    public static class Program
    {
        public static void Main(string[] args)
        {
            // here you initialize structuremap from the config file.
            // You could probably use a FileSystemWatcher to reinitialize 
            // whenever the structuremap.config file changes
            ObjectFactory.Initialize(x =>
            {
                x.UseDefaultStructureMapConfigFile = true;
            });

            var concrete = ObjectFactory.GetInstance<AbstractBase>();

            concrete.Method1();

            Console.ReadKey(true);
        }
    }
}

AbstractBase.cs:

namespace DemoIoC
{
    public abstract class AbstractBase
    {
        public abstract void Method1();
    }
}

ConcreteImplementation1.cs:

namespace DemoIoC
{
    using System;

    public class ConcreteImplementation1 : AbstractBase
    {
        public override void Method1()
        {
            Console.WriteLine("Called ConcreteImplementation1");
        }
    }
}

【讨论】:

  • 完美!这正是我需要的推动力。
  • 只是一个简单的问题。抽象类接收一个 StreamReader 作为 ctor 参数。如何通过 XML 配置文件指示它?类似
  • 看看stackoverflow.com/questions/2824088/…,它展示了如何使用仅在运行时知道的参数创建一个对象,但不清楚如何在 XML 配置中指定它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-16
  • 2016-03-23
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
相关资源
最近更新 更多