结构图(或任何IoC,真正的)架构问题

时间:2009-12-03 15:52:55

标签: architecture dependency-injection inversion-of-control structuremap

我将使用structuremap来处理我正在进行的项目。基本要点是我有一个带有NHibernate实现的存储库模式,但我想使用StructureMap来加载存储库,以防我决定切换到Linq2Sql或其他类型的实现。我知道如何初始化structuremap,但我的问题是在哪里?使用我的库的Web应用程序是否应负责配置注册表?我的库中是否应该有默认实现?它最适合哪里?

目前我的图书馆结构如下:

  • Library.Data
  • Library.Data.NHibernate
  • Library.Domain

.Domain命名空间包含实际实体,而.Data命名空间包含存储库的接口。 .Data.NHibernate命名空间包含这些接口的NHibernate实现。

3 个答案:

答案 0 :(得分:2)

使用IoC容器时,理想情况下,调用应用程序应负责配置所有依赖项。

结构良好的系统将要求依赖对象作为构造函数参数。如何调用这些构造函数独立于StructureMap或任何其他技术,但只能在使用“最顶层”对象的位置指定。以这种方式进行分离将允许应用程序以他们想要的方式注入依赖关系,并为您提供温暖的模糊感觉,您只能从关注点的分离中获得。

我不完全确定你的库中的“默认”实现是什么意思。您的“默认”实现(由StructureMap注册表配置)将是您在向StructureMap询问给定接口的实现时可能得到的实例(在您的情况下可能是某种IRepository),而不指定任何其他条件。

对于您,您将希望将此实例配置为NHibernate实现。据推测,这个实现已经作为“NHibernate Repository”存在于Library.Data.NHibernate命名空间中。除非您想将IRepository实现更改为其他实现,否则您不需要创建任何其他实现。

答案 1 :(得分:2)

前段时间我有同样的问题,最后我结束了在每个项目上创建一个注册表类并以级联方式调用它们。

当我回到家时,我会用一些代码更新。

<强>更新

我有3个项目(Web,服务和数据),但我不想在我的Web项目中添加对Data的引用,所以我所做的是每个项目都负责注册它自己的Interfaces。

例如,在我的Web项目中,我创建了WebRegistry类,它不仅注册了自己的类型,还调用了Services项目中的ServicesRegistry类,依此类推。

<强> WebRegistry:

public class WebRegistry : Registry
{
    public WebRegistry()
        {
            ObjectFactory.Configure(x =>
            {
                //call to ServicesRegistry in my services project
                x.AddRegistry(new ServicesRegistry());

                //Register your web classes here
                ForRequestedType... blablablabla

            });

        }
}

<强> ServicesRegistry:

public class ServicesRegistry : Registry
{
    public ServicesRegistry()
    {
        ObjectFactory.Configure(x =>
        {
            x.AddRegistry(new DataRegistry());

            //Register your services classes here
            ForRequestedType... blablablabla
        });

    }
}

最后是DataRegistry:

public class DataRegistry : Registry
{
    public DataRegistry()
    {
        ObjectFactory.Configure(x =>
        {
            ForRequestedType blablbabla....

        });
    }
}

我认为这样一切都完全独立,你只需要调用global.asax中的webregistry来配置整个应用程序:

/// <summary>
/// 
/// </summary>
public class Bootstrapper
{

    /// <summary>
    /// 
    /// </summary>
    public static void ConfigureStructureMap()
    {
        ObjectFactory.Initialize(x =>
        {
            x.AddRegistry(new WebRegistry());
        });
    }


}

<强>的Global.asax:

    protected void Application_Start()
    {

        Bootstrapper.ConfigureStructureMap();


    }

答案 2 :(得分:0)

控制配置的反转可以在两个地方之一完成:在调用程序集中或在另一个程序集中。

如果你想在调用程序集(将它与IOC工具耦合)中执行它,只需在Global.asax.cs或在那里调用的类中执行。

如果要在其他程序集中执行此操作,请使用HTTP模块,如下所示: http://codecampserver.googlecode.com/svn/trunk/src/DependencyResolution/DependencyRegistrarModule.cs