用参数覆盖包装ioc解析

时间:2016-01-05 20:58:32

标签: c# unity-container dry

所以,这是我正在考虑的一个问题,可以使用一些帮助。首先,我正在使用Unity for IOC,并希望使用它来解析和生成SQL调用的包装器实例。为此,我有一个实现ISqlWrapper的SqlWrapper。它有两个结构。这是相关的代码片段。

public interface ISqlWrapper : IDisposable
{
    string CommandText { get; set; }
    void Execute();
}

public class SqlWrapper : ISqlWrapper, IDisposable
{
    public SqlWrapper(string connectionString);
    public SqlWrapper(IDbConnection sqlConnection);

    string CommandText { get; set; }
    void Execute();
}

显然,约不是完整的代码,它是为了说明实现的相关部分。

对于我的应用程序,我只使用带有connectionString的构造函数。所以,在我的IoC容器中,我注册了以下内容......

_unityContainerontainer.RegisterType<ISqlWrapper, SqlWrapper>( new InjectionConstructor(typeof(string)));

现在,这就是事情变得有趣的地方。我想要做的是实现一个允许我轻松解析ISqlWrapper实例的方法。我已将代码归结为此方法。

ISqlWrapper CreateSqlWrapper(string connectionString)
{
    ParameterOverrides parameterOverride = new ParameterOverrides();
    parameterOverride.Add("connectionString", connectionString);
    return _iocContainer.Resolve<ISqlWrapper>(parameterOverride);
}

但是,目前我正在将此方法的副本放入我用来连接数据库的每个类中。

public class ExampleClass1 : IExampleClass1
{
    private readonly IIocContainer _iocContainer;

    ISqlWrapper CreateSqlWrapper(string connectionString)
    {
        ParameterOverrides parameterOverride = new ParameterOverrides();
        parameterOverride.Add("connectionString", connectionString);
        return _iocContainer.Resolve<ISqlWrapper>(parameterOverride);
    }

    public ExampleClass1(IIocContainer iocContainer)
    {
        _iocContainer = iocContainer;
    }

    public void DoStuff(string connectionString)
    {
        using( ISqlWrapper sqlWrapper = CreateSqlWrapper(connectionString))
        {
            CommandText = "Select * from Table*";
            Execute;
        }
    }
}

所以,问题是我需要在每个类中都有一个CreateSqlWrapper实例,以便更容易地实现ISqlWrapper的实例。我知道我可以使用继承将此方法实现到父类中。但是,我试图看看是否有更好的解决方案来解决这个问题。

有没有人对如何定义CreateSqlWrapper方法有任何想法,而无需将其复制并粘贴到每个类中?

2 个答案:

答案 0 :(得分:0)

请参阅此答案:How to create objects using a static factory method?

您可以使用InjectionFactory并在配置期间传递代理。

答案 1 :(得分:0)

我已经阅读了所有人都说过的内容,并认定Gian Paolo发布了最好的建议。基本上我需要实施一个工厂。所以这就是我所做的。

Gian Paolo如果您发布答案,我会根据您的评论接受。

为工厂方法创建了一个接口和类。

public interface ISqlWrapperFactory
{
    ISqlWrapper CreateInstance(string connectionString);
}

public class SqlWrapperFactory:ISqlWrapperFactory     {         private readonly IIocContainer _iocContainer;

    public SqlWrapperFactory(IIocContainer iocContainer)
    {
        _iocContainer = iocContainer;
    }

    public ISqlWrapper CreateInstance(string connectionString)
    {
        ParameterOverrides parameterOverride = new ParameterOverrides();
        parameterOverride.Add("connectionString", connectionString);
        return _iocContainer.Resolve<ISqlWrapper>(parameterOverride);
    }
}

将其注册到IoC容器中。

_unityContainerontainer.RegisterType<ISqlWrapperFactory, SqlWrapperFactory>();

然后按如下方式修改了类。

public class ExampleClass1 : IExampleClass1
{
    private readonly IIocContainer _iocContainer;
    private readonly ISqlWrapperFactory _sqlWrapperFactory;


    public ExampleClass1(IIocContainer iocContainer, ISqlWrapperFactory sqlWrapperFactory)
    {
        _iocContainer = iocContainer;
        _sqlWrapperFactory = sqlWrapperFactory;
    }

    public void DoStuff(string connectionString)
    {
        using( ISqlWrapper sqlWrapper = _sqlWrapperFactory.CreateInstance(connectionString))
        {
            CommandText = "Select * from Table*";
            Execute();
        }
    }
}

这意味着工厂方法只需要声明一个 - 干涸:) 实现ISqlWrapper的代码仍然是一个单行程序。这意味着有人不太可能搞乱它。

我以为我会完整发布此内容,以便其他人可以看到此问题的解决方案。基本上,将参数传递给构造函数会使其与其他解决方案不同。