English 中文(简体)
Structuremap (or any IoC, really) architecture question
原标题:

I m going to use structuremap for a project I m working on. The basic gist is that I have a repository pattern with an NHibernate implementation, but I want to use StructureMap to load the repositories in case I ever decide to switch to a Linq2Sql or other type of implementation. I know how to initialize structuremap, but my question is where? Should the web application that uses my library be responsible for configuring the registry? Should I have a default implementation in my library? Where would it fit best?

My library structure at the moment looks like:

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

The .Domain namespace contains the actual entities, while the .Data namespace contains the interfaces for the repository. The .Data.NHibernate namespace contains the NHibernate implementation of those interfaces.

最佳回答

When using IoC containers, the calling application should ideally be responsible for configuring all dependencies.

A well-structured system will demand dependent objects as constructor parameters. How you invoke those constructors is independent of StructureMap or any other technique, but can only be specified at the point at which the "top most" object is used. Separation in this way will allow applications to inject dependencies in whichever way they desire and gives you that warm fuzzy feeling you can only get from having great separation of concerns.

I m not entirely sure what you mean by a "default" implementation in the context of your library. Your "default" implementation (configured by your StructureMap registry) will be the instance you get back when you ask StructureMap for an implementation of a given interface (presumably some kind of IRepository in your case), without specifying any other criteria.

For you, you will want this instance to be configured as your NHibernate implementation. Presumably this implementation already lives in the Library.Data.NHibernate namespace as your "NHibernate Repository". You shouldn t need to create any other implementation unless you want to change your IRepository implementation to something else.

问题回答

I had the same question some time ago and finally i ended creating a registry class on each project and calling them in cascade.

I ll update with some code when i get home.

Update

I had 3 projects (Web, Services and Data) but i did not want to add a reference to Data in my Web project for example, so what i did is that every project is responsible of registering it s own Interfaces.

For example, In my Web project i created the class WebRegistry that not only register its own types but also calls the ServicesRegistry class in my Services project and so on.

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
        });

    }
}

And finally the DataRegistry:

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

        });
    }
}

I think this way everything is completely idependant and you only need one call to the webregistry in your global.asax to configure the entire application:

/// <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();


    }

Inversion of control configuration can be done in one of two places: in the calling assembly or in another assembly.

If you want to do it in the calling assembly (which couples it to the IOC tool), just do it in Global.asax.cs or in a class called there.

If you want to do it in another assembly, use an HTTP Module, like this: http://codecampserver.googlecode.com/svn/trunk/src/DependencyResolution/DependencyRegistrarModule.cs





相关问题
SQL Server - How many users do I *really* need?

I m setting up an application, and I m looking into purchasing a license for SQL Server. My question is pretty simple (though may have a complicated answer...) How many users accounts do I really ...

Object Graph / Persistence Question

I m currently working with an online application that requires multiple screens/steps in order to complete. The application domain is modeled using an object graph. Persistence to and from a database ...

Why does stack get truncated in Exception.StackTrace?

Why does the high part of the stack (in Exception.StackTrace) gets truncated? Let s see a simple example: public void ExternalMethod() { InternalMethod(); } public void InternalMethod() { try ...

ASP.NET MVC and Service Oriented Architecture

I would like to know how do i incorporate a feature like wcf within and MVC application. My current idea of the architecture is as follows: EntityFramework -> ASP.NET MVC (Views) ...

热门标签