nTier +运行时分辨率中的依赖注入

时间:2012-05-21 09:23:11

标签: c# .net wcf dependency-injection

我一直在阅读依赖注入(Mark Seemann: Dependency Injection in .NET和各种文章),以帮助我的团队开发基于EntityFramework,WCF和WPF的新3层应用程序。

我认为我们需要在每个层上使用Composition Root,因为它们通过服务进行通信( DAL < - > WCF< - > BL < ; - > WCF< - > PL / UI )。

我们的一个要求是我们需要动态加载和配置EF,以便我们可以在应用程序部署后更改/扩展我们的模型。

我们的BL没有详细介绍 - > PL / UI实现,让我们专注于通过自定义serviceHost后面的EntityService公开的DAL。我们的项目有一个简单的例子如下:

Project.DataModel

  • 单一程序集
  • 硬参考:无
  • 运行时解析:无
  • 一个公共库,它为数据建模提供抽象类和接口。即EntityData抽象类

Project.DataModel。[?]数据

  • 许多程序集:即CityData,CustomerData等
  • 硬参考:Project.DataModel
  • 运行时解析:无
  • 定义基于EntityData的单个或多个实体的组件

Project.DataModel。[?] DataConfiguration

  • 许多程序集:即CityDataConfiguration,CustomerDataConfiguration等
  • 硬引用:Project.DataModel。[?] Data,EntityFramework
  • 运行时解析:无
  • 为前一个程序集中定义的实体定义EntityTypeConfiguration的组件。

Project.DataAccess

  • 单一程序集
  • 硬参考:Project.DataModel,EntityFramework
  • 运行时解析:Project.DataModel。[?] Data,Project.DataModel。[?] DataConfiguration
  • 通过EntityManager(抽象)提供DbContext的数据访问库。在运行时,此程序集查看配置或目录,加载EntityTypes及其等效的EntityTypeConfigurations并动态创建模型。

Project.ServiceModel.EntityDataService

  • 单一程序集
  • 硬引用:Project.DataModel,Project.DataAccess
  • 运行时解析:无
  • 通过EntityManager类在EntityData对象上提供CRUD操作的通用服务。

Project.ServiceModel.EntityDataServiceContract

  • 单一程序集
  • 硬引用引用:Project.DataModel
  • 运行时解析:Project.DataModel。[?] Data
  • 公开服务合同并需要定义ServiceKnownTypes,因此我们需要运行时解析EntityTypes。

Project.ServiceHost

  • 单一程序集
  • 硬参考:无
  • 运行时解析:Project.ServiceModel。[?] Service,Project.ServiceModel。[?] ServiceContract
  • 自定义ServiceHost,它将在运行时(通过配置或目录扫描)解析和加载各种服务,如EntityDataService。

这感觉很像插件项目,我们在编译时不太了解,并且程序集之间没有太多的硬引用。

在这种情况下,您将如何实施DI?我真的无法理解如何以及在何处使用DI或DI容器,组合根和批次。

非常感谢您的意见。

1 个答案:

答案 0 :(得分:-1)

人们有办法让依赖注入过于复杂。如果FirstClass需要一个ISecondClass来工作,那么只要确保它没有一个就可以构建。组合根本质上是一个类,其依赖关系可以跟随其他所有内容。确保你的接口都有注册实例(单例生命周期通常可以很好地完成工作),实例化组合根,大多数东西应该“正常工作”。如果没有,那么事情就会比它需要的更多。

WizBang应用程序可能如下所示:

interface IThingDoerA
{
}

class ThingDoerA : IThingDoerA
{
}

interface IThingDoerB
{
}

class ThingDoerB : IThingDoerB
{
    private readonly IThingDoerA _tda;
    public ThingDoerB(IThingDoerA tda)
    {
        _tda = tda;
    }
}

interface IThingDoerC
{
}

class ThingDoerC : IThingDoerC
{
    private readonly IThingDoerA _tda;
    private readonly IThingDoerB _tdb;
    public ThingDoerC(IThingDoerA tda, IThingDoerB tdb)
    {
        _tda = tda;
        _tdb = tdb;
    }
}

// I am the composition root.
interface IWizBang
{
    public void StartApp();
}

class WizBang : IWizBang
{
    private readonly IThingDoerA _tda;
    private readonly IThingDoerC _tdc;
    public WizBang(IThingDoerA tda, IThingDoerC tdc)
    {
        _tda = tda;
        _tdc = tdc;
    }

    public void StartApp()
    {
        //TODO
        // _tda.Blah()
        // _tdc.Blah()
    }
}

就WPF而言,看起来您可以在System.Windows.Application子类中进行一些轻量级方法调用,以使您的应用程序运行。