.NET StructureMap IOC请求实例并传递参数

时间:2012-11-29 11:52:26

标签: .net arguments structuremap

我正在尝试向StructureMap询问一个实例并立即传递参数,以获得可配置的实例(使用我传递的参数),但我不知道该怎么做!

这是代码,很容易理解我想做什么。

class MyRegistry : Registry {

public MyRegistry() {

    // Use a new Connection for each instance
    For<ISQLRepositoryCommands>().Use(x => new SQLRepositoryCommands(DatabaseConnections.NewSqlConnection()));

    // WHAT I Want to do is.. remove the line above of code and let only this.
    For<ISQLRepositoryCommands>()
    .Use(x => {
        if( x.arguments != null ) {
            // Specific connection passed by parameter
            return new SQLRepositoryCommands( (SqlConnection) x.arguments[0]);
        }       
        // default connection
        return new SQLRepositoryCommands(DatabaseConnections.NewSqlConnection());
    }); 
}   

}

主要

public static class StartUseStructureMap {
public static void Main() {
    // SQLRepositoryCommands with default connection associated
    var def = ObjectFactory.GetInstance<ISQLRepositoryCommands>();

    // SQLRepositoryCommands with custom connection associated
    var personalizedConnection = new SqlConnection("cstring");
    var personalized = ObjectFactory.GetInstance<ISQLRepositoryCommands>(new Arguments[] { new Argument(personalizedConnection) };
}

}

1 个答案:

答案 0 :(得分:0)

这个伪代码只是我的看法,也许有更好的方法来实现它。但这就是我要做的。

您可以使用的一件事是工厂模式,但为此您可以略微调整您的代码。 但在我们开始这一步之前,我们必须摆脱您注册码中SqlConnection的直接使用。虽然StructureMap不需要显式注册所有对象,但我们可以做一个我们可以在StructureMap中注册的包装器,并且每次创建SqlConnection时都会调用它。这样我们可以在那里创建一个SqlConnection的逻辑,它依赖于连接字符串(空或不)。这是它的样子:

public interface ISQLConnectionWrapper
{
      SqlConnection GetConnection(string connectionName);
}

public class SQLConnectionWrapper : ISQLConnectionWrapper
{
    public SqlConnection GetConnection(string connectionName)
    {
        if (string.IsNullOrWhiteSpace(connectionName))
            return DatabaseConnections.NewSqlConnection();
        return new SqlConnection(connectionName);
    }
}

然后我们可以调整一个小的SQLRepositoryCommands类,以便在构造函数中获取一个构建器,它将返回一个知道要创建哪个连接的包装器:

public class SQLRepositoryCommands : ISQLRepositoryCommands
{
    private readonly Func<string, ISQLConnectionWrapper> _aBuilder;
    public SQLRepositoryCommands(Func<string, ISQLConnectionWrapper> aBuilder)
    {
        // guard clause first of course.
        _aBuilder = aBuilder;
    }

    public void DoWork(string connectionName = null)
    {
        var connection = _aBuilder(connectionName);
    }
}

我添加了Doact方法,它实际上使用构建器来获得正确的连接并完成工作。

然后,您可以注册它:

// register
ObjectFactory.Initialize( c =>
    {
              c.For<ISQLConnectionWrapper>().Use<SQLConnectionWrapper>();
              c.For<Func<string, SqlConnection>>().Use(d => (s => ObjectFactory.GetInstance<ISQLConnectionWrapper>().GetConnection(s)));
        c.For<ISQLRepositoryCommands>().Use<SQLRepositoryCommands>();
    });

以下是您可以使用它的方法:

// use
var command = ObjectFactory.GetInstance<ISQLRepositoryCommands>();
command.DoWork("MyConnection"); // specific connection
command.DoWork(); // default connection

正如我所说。也许有更好的方法可以做到,但这段代码应该有用。