0

我试图向 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) };
}

}

4

1 回答 1

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);
    }
}

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

那么这里是你如何注册它:

// 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

就像我说的。也许有更好的方法可以做到这一点,但这段代码应该可以工作。

于 2012-11-30T09:22:46.363 回答