Architecture Structuremap(或任何IoC,真的)架构问题

Architecture Structuremap(或任何IoC,真的)架构问题,architecture,dependency-injection,inversion-of-control,structuremap,Architecture,Dependency Injection,Inversion Of Control,Structuremap,我将使用structuremap进行我正在进行的一个项目。基本要点是,我有一个带有NHibernate实现的存储库模式,但我想使用StructureMap加载存储库,以防我决定切换到Linq2Sql或其他类型的实现。我知道如何初始化structuremap,但我的问题是在哪里?使用我的库的web应用程序是否应该负责配置注册表?我的库中是否应该有默认实现?哪里最合适 目前我的库结构如下所示: 图书馆.数据 Library.Data.NHibernate 图书馆.域名 .Domain命名空间包含

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

目前我的库结构如下所示:

  • 图书馆.数据
  • Library.Data.NHibernate
  • 图书馆.域名

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

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

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

我不完全确定在您的库上下文中“默认”实现是什么意思。您的“默认”实现(由StructureMap注册表配置)将是当您向StructureMap请求给定接口的实现(在您的情况下可能是某种类型的
IRepository
)而不指定任何其他条件时返回的实例


对于您来说,您希望将此实例配置为您的NHibernate实现。大概这个实现已经存在于
Library.Data.NHibernate
命名空间中,作为“NHibernate存储库”。您不需要创建任何其他实现,除非您想将您的
IRepository
实现更改为其他实现。

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

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

我不完全确定在您的库上下文中“默认”实现是什么意思。您的“默认”实现(由StructureMap注册表配置)将是当您向StructureMap请求给定接口的实现(在您的情况下可能是某种类型的
IRepository
)而不指定任何其他条件时返回的实例


对于您来说,您希望将此实例配置为您的NHibernate实现。大概这个实现已经存在于
Library.Data.NHibernate
命名空间中,作为“NHibernate存储库”。您不需要创建任何其他实现,除非您想将您的
I假设
实现更改为其他实现。

不久前我也遇到了同样的问题,最后我结束了对每个项目创建注册表类并以级联方式调用它们

我回家后会更新一些代码

更新

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

例如,在我的Web项目中,我创建了WebRegistry类,它不仅注册自己的类型,而且在我的服务项目中调用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

            });

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

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

    }
}
    protected void Application_Start()
    {

        Bootstrapper.ConfigureStructureMap();


    }
服务注册:

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

            });

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

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

    }
}
    protected void Application_Start()
    {

        Bootstrapper.ConfigureStructureMap();


    }
最后是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());
        });
    }


}

不久前我也遇到了同样的问题,最后我在每个项目上创建了一个registry类并在cascade中调用它们

我回家后会更新一些代码

更新

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

例如,在我的Web项目中,我创建了WebRegistry类,它不仅注册自己的类型,而且在我的服务项目中调用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

            });

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

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

    }
}
    protected void Application_Start()
    {

        Bootstrapper.ConfigureStructureMap();


    }
服务注册:

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

            });

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

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

    }
}
    protected void Application_Start()
    {

        Bootstrapper.ConfigureStructureMap();


    }
最后是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());
        });
    }


}

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

如果您想在调用程序集中(将其与IOC工具耦合)执行此操作,只需在Global.asax.cs或在那里调用的类中执行即可

如果要在其他程序集中执行此操作,请使用HTTP模块,如下所示:

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

如果您想在调用程序集中(将其与IOC工具耦合)执行此操作,请使用JU