依赖注入容器 [英] Dependency Injection Container

查看:165
本文介绍了依赖注入容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据访问层库,我想使便携式。我喜欢它是便携式的原因是因为我想与SQL Azure的&放工作; Azure的文件存储(例如:数据+ PDF报告),以及与SQL Server 2008R2和文件系统存储一个具体的服务器上。

I have a Data Access Layer library that I would like to make "portable". The reason I like it to be portable is because I want to work with SQL Azure & Azure File Storage (eg, data + pdf reports) as well as Sql Server 2008R2 and File System storage on a concrete server.

根据规范系统应该去生活在后来的执行(SQL +文件系统存储),而在会议的的可伸缩性门槛我们计划迁移到Azure上。

Based on spec the system is supposed to go live with the later implementation (sql + file system storage), while upon a meeting a certain scalability threshold we plan on moving to Azure.

我用工具IDataProvider接口(我建的),它定义了所有数据访问的具体落实方法应该具有数据访问类。

The data access class I use implements IDataProvider interface (which I built) and it defines the methods that any data access concrete implementation should have. Consuming the data access layer is done via passing the IDataProvider interface and calling methods on it eg:

public Interface IDataProvider
{
    public bool DoSomething();
}

public class AzureDataProvider : IDataProvider
{
    private string ConnectionString;

    public AzureDataProvider(string connectionString)
    {
        this.ConnectionString = connectionString;
    }

    public AzureDataProvider():this(
        ConfigurationManager.ConnectionString["conn"].ConnectionString)
    {
    }

    public bool DoSomething()
    {
        return false;
    }
}



所以,现在的问题是,消费类会在IDataProvider接口的调用方法有做到以下几点:

So now the issue is that the consumer class that would call methods on the IDataProvider interface has to do the following:

public class DataAccessConsumer
{
    public void SomeOperation()
    {
        AzureDataProvider azureProvider = new AzureDataProvider();
        IDataProvider dataProvider = (IDataProvider)azureProvider;

        bool result = dataProvider.DoSomething();
    }
}



因此,与上面的代码的问题是,客户端仍然有混凝土AzureDataProvider类的知识。我想有提供客户端只用IDataProvider接口,而不通过连接字符串到每一个接口的方法,或查找连接字符串通过ConfigurationManager中的每一个方法中的方法。

So the issue with the above code is that the client still has to have knowledge of the concrete AzureDataProvider class. I want to have a method of providing the client with just the IDataProvider interface, without passing a connection string to every interface method, or looking up the connection string within every method via the ConfigurationManager.

这可能吗?将抽象工厂或某种依赖注入容器模式做的伎俩?如果是这样,我将不胜感激代码样本,或链接代码示例。

Is that possible? Would Abstract Factory or some sort of Dependency Injection Container pattern do the trick? If so, I would appreciate code samples, or links to code samples.

推荐答案

好吧,我推出了自己的DI。如果目标是实现可移植性话,我想我已经到了一个半接受的解决方案。 。缺点是,你不能真正实现了全DI,但在我的应用是足够好的背景下

Well, I rolled out my own DI. If the goal is to achieve portability then I think I have come to a semi-acceptable solution. The disadvantages are that you cannot truly achieve a full DI, however in the context of my application it is good enough.

接口:

public interface IConnection
{
    public string ConnectionString;
}



混凝土连接实施

public class Connection: IConnection
{
    public string ConnectionString{ get; set; }

    public Connection(string connectionString)
    {
        this.ConnectionString = connectionString;
    }

    public Connection():this(ConfigurtionManager.ConnectionStrings["connection"].ConnectionString)
    {
        //Broke DI in the interest of usability.
    }
}

数据访问层接口

public interface IDataProvider
{
    IConnection Connection;

    public void Foo();
}



具体的数据访问层实施

public class AzureProvider : IDataProvider
{
    IConnection Connection { get; set; }

    public AzureProvider(IConnection connection)
    {
        this.Connection = connection;
    }

    public void Foo()
    {

    }
}

DI Conainer /工厂(单身或静态类)

public static class ProviderFactory
{
    public static IDataProvider GetProvider()  //I'd pass parameters if I had more than 1.
    {
        Connection connection = new Connection(); //this is why I broke DI.
        IConnection iConnection = (IConnection)connection;

        AzureProvider azureProvider = new AzureProvider(iConnection);
        IDataProvider iDataProvider = (IDataProvider)azureProvider;

        return iDataProvider;
    }
}

数据访问层消费(在此示例这是一个页面):

public class SomePage : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        IDataProvider provider = ProviderFactory.GetProvider();
        provider.Foo();
    }
}



正如你可以看到,页面不需要了解任何的数据访问层的实现细节。只要ProviderFactory可吐IDataProvider,页面是幸福的。因此,如果我们决定更换供应商,说SqlStorageProvider,只要它实现IDataProvider界面,页面的代码不会被改变。这实现了在软件架构方面的担忧真正的分离。

As you can see, the page doesn't need to know any of the implementation details of the data access layer. As long as the ProviderFactory can spit IDataProvider, the page is happy. Therefore, if we decide to change providers, say SqlStorageProvider, as long as it implements IDataProvider Interface, the Page's code will not have to be changed. This achieves true separation of concerns in terms of software architecture.

这篇关于依赖注入容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆