Xml配置还是通过代码配置?

Ami*_*rge 10 structuremap dependency-injection inversion-of-control

我个人喜欢从C#代码配置StructureMap的选项.根据我的理解,DI的优点之一是我们可以轻松交换新的具体实例.但是,如果配置是在代码中定义的,那么具体实例在dll中是硬编码的.

所以,实际上,它与硬件编码依赖关系一样好,对吧?我知道,在测试过程中它会让生活更轻松......

我的观点是,使用xml配置不是更好吗?你想插入一个新的具体实例?只需让安装程序用新的文件覆盖structuremap.config文件.

那么,配置StructureMap的首选方法是什么?

额外:我暂时被迫使用C#配置,因为我不知道如何将连接字符串传递给实例.我可以在配置文件中编写连接字符串,但我想重用app.config中定义的连接字符串.

Mar*_*ann 17

无论您使用哪个特定的DI容器,都应该始终将应用程序对象图的分辨率推迟到最后一个负责的时刻.这称为应用程序的组合根.

您可以编写大部分应用程序,而无需引用DI容器.这也意味着您可以在代码或配置之间推迟配置,直到您需要它为止.

根本不需要容器进行单元测试,但可能需要它进行集成测试.但是,在集成测试中,您可能需要与最终应用程序不同的容器配置.

总而言之,如今,在代码中配置容器是首选方法,因为它更强大,您可以应用基于约定的配置机制.

XML配置往往更脆弱,更冗长.在大多数情况下,它只会减慢您的速度,因为您没有重构或编译器支持.

但是,当您需要能够交换依赖项而不重新编译应用程序时,XML配置仍然有效.大多数DI容器都允许您混合这些方法,以便您可以在代码中使用大部分配置,但出于可扩展性原因,在XML中定义了一些选定的依赖项.


Kev*_*evM 6

要回答你的问题,你可以在StructureMap中吃蛋糕并吃掉它.您可以从代码配置容器,并从应用程序配置中推送您需要的额外配置.这就是EqualToAppSetting的用途.

创建一个设置类

    public class DatabaseSettings
{
    public DatabaseSettings(string type, string connectionString)
    {
        Type = type;
        ConnectionString = connectionString;
    }

    public string Type { get; set; }
    public string ConnectionString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

接下来告诉StructureMap使用您的应用程序设置对其进行配置.

        [Test]
    public void setup_concrete_class_via_application_configuration()
    {
        var container = new Container(config =>
        {
            config.ForConcreteType<DatabaseSettings>().Configure
                .Ctor<string>("type").EqualToAppSetting("dovetail.database.type", "mssql")
                .Ctor<string>("connectionString").EqualToAppSetting("dovetail.database.connectionString");

        });

        var databaseSettings = container.GetInstance<DatabaseSettings>();
        databaseSettings.Type.ShouldEqual("mssql");
        databaseSettings.ConnectionString.ShouldEqual("Data Source=.; Initial Catalog=dovetail;User Id=sa;Password=sa;");
    }
Run Code Online (Sandbox Code Playgroud)

最后,这是我的应用程序配置中的应用程序设置:

    <appSettings>
    <add key="dovetail.database.type" value="mssql"/>
    <add key="dovetail.database.connectionString" value="Data Source=.;Initial Catalog=dovetail;User Id=sa;Password=sa;"/>    
</appSettings>
Run Code Online (Sandbox Code Playgroud)