带有IOC的c#中的数据访问层(依赖注入)

时间:2014-10-03 16:50:41

标签: asp.net-mvc interface database-connection inversion-of-control data-layer

我正在尝试在C#中构建多层应用程序(服务)。确切地说,我正在尝试使用ASP.NET Web Api构建一个REST Web服务,它将自己托管(使用Owin)。现在我到目前为止,我有以下组件(每个组件都在一个单独的.dll中):

     - RestHost(在我的情况下是一个控制台应用程序)
     - RestService(这是我的所有控制器的web服务)
     - InterfacesLayer
     - ModelLayer(这里是我使用的对象,只是使用它们的get / set方法)
     - DataLayer(ModelLayer中的每个类在Datalayer中都有自己的类,另外还有数据库连接类)      - BusinessLayer(这里完成所有逻辑,同样来自model的每个类都有自己的类,这个层与REST服务和数据层进行通信)。

RestHost - 顾名思义,它是我服务的主人。除此之外,我也在这里进行依赖注入。由于代码不多,我会发布它:

static void Main(string[] args)
    {

        IUnityContainer container = new UnityContainer();
        // Dependency Resolving
        container.RegisterType<IAktData, AktDataImpl>(new HierarchicalLifetimeManager());
        container.RegisterType<IAktService, AktServiceImpl>(new HierarchicalLifetimeManager());

        container.RegisterType<ILeistungData, LeistungDataImpl>(new HierarchicalLifetimeManager());
        container.RegisterType<ILeistungService, LeistungServiceImpl>(new HierarchicalLifetimeManager());

        container.RegisterType<IPersonData, PersonDataImpl>(new HierarchicalLifetimeManager());
        container.RegisterType<IPersonService, PersonServiceImpl>(new HierarchicalLifetimeManager());

        container.RegisterType<IPersistent, FirebirdDB>(new HierarchicalLifetimeManager());


        string serverAddress = ConfigurationManager.AppSettings["serverAddress"];
        string connectionString = ConfigurationManager.ConnectionStrings["connectionStrings"].ConnectionString;

        using (RESTService.StartServer(container, serverAddress,connectionString )) 
        {

            Console.WriteLine("Server started @ "+ DateTime.Now.ToString() + " on " + serverAddress + "/api");
            Console.ReadLine();
        }
    }

哦,我忘了提及,但你可以从代码中看到它,在我的主机应用程序中我也在阅读我的连接字符串托管的App.Config。
这是我的问题。我不知道如何从我的服务访问数据库连接。这里我在我的数据访问层实现Firebird,但我不确定如何在我的应用程序中使用它。当然最简单的方法就是创建一个实例并将其传递给我的服务,但这是我想要做的最后一件事。我一直在考虑将Firebird作为静态类或单例实现,但是我不能使用我的IPersistant接口(除此之外,我不认为这是正确的方法)。
所以我的问题是,这种东西有什么最好的做法吗?我不知何故需要将连接字符串传递给IPersistent(Firebird)的实现,但实际上没有在我的RESTService中创建Firebird实例。

由于

1 个答案:

答案 0 :(得分:0)

多层应用程序(如您正在构建的应用程序)的一般模式是拥有一个数据层,通过存储库为您的服务提供对数据库的访问,或者其他一些持久化数据的方法。

然后,您可以配置IoC容器以将连接字符串注入存储库,然后将存储库注入您的服务。这样,您的服务就数据的持久性保持不可知,并且可以专注于定义业务逻辑。

我实际上为存储库做了类似的事情,而不是在数据库中保存数据,而是将其存储在Azure的CDN上的blob中。使用我的IoC(在我的情况下为StructureMap)的配置如下所示:

string storageApiKey = ConfigurationManager.AppSettings["CloudStorageApiKey"];
string storageUsername = ConfigurationManager.AppSettings["CloudStorageUsername"];
this.For<IImageStorageRepository>().Use<ImageStorageRepository>().Ctor<string>("storageApiKey").Is(storageApiKey).Ctor<string>("storageUsername").Is(storageUsername);

我的存储库看起来像这样:

public class ImageStorageRepository : IImageStorageRepository
{
    ....
    public ImageStorageRepository(string storageApiKey, string storageUsername)
    {
        this.cloudIdentity = new CloudIdentity() { APIKey = storageApiKey, Username = storageUsername };
        this.cloudFilesProvider = new CloudFilesProvider(cloudIdentity);
    }
    ....
}
相关问题