依赖注入 - 通过配置文件在运行时选择DLL和类实现

时间:2011-06-15 23:14:20

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

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

现在使用 AbstractClass 我在两个不同的dll上实现了它:

  • First.API.Implementation.dll ConcreteImplementation1
  • Second.API.Implementation.dll ConcreteImplementation2

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和实现之外,我还需要指出该应用程序要使用的文件。我可以在同一个文件中指明其路径吗?

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

感谢。

1 个答案:

答案 0 :(得分:2)

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

structuremap.config:

<?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有很多选项,例如单身,瞬态等

的Program.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");
        }
    }
}