Castle Windsor: Register components across multipl

2019-02-18 21:27发布

I would like to use Castle Windsor for dependency injection for my solution consisting of the following projects:

  1. Mvc [ASP.NET MVC 3 Web Application]: presentation layer (depends on Business and Models)
  2. Business [Class Library]: business layer (depends on DataAccess and Models)
  3. DataAccess [Class Library]: data access layer (depends on Models)
  4. Models [Class Library]: model layer

In the business layer there is a class called PostService implementing IPostService that manages blog posts. The PostsController of the Mvc project depends on IPostService. However, PostService (the corresponding concrete implementation) itself depends on IPostRepository.

Where do I configure Castle Windsor to return an instance of PostRepository to resolve IPostRepository? The Mvc project doesn't know about the DataAccess project. Thus, I can't configure the component bindings in global.asax or somewhere else within Mvc.


[Update] Dependency Diagram

Now that I've found a solution (thanks again, Darin Dimitrov!) I'd like to share the current dependency diagram with you.

Project dependencies

4条回答
2楼-- · 2019-02-18 21:39

You have to ask yourself one thing: "do I really need 4 different assemblies for my MVC project?" You should break the code into assemblies according to deployment boundaries, not just based on some vague notion that Model code should be physically separate from Business code & similar. You should use namespaces for such things instead of separate projects.

Here's a good article on this issue: Advices on partitioning code through .NET assemblies by Patrick Smacchia.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-02-18 21:47

Create and place Windsor installer classes (IWindsorInstaller interface implementations) in your class libraries, for example:

public class PostRepositoryInstaller: IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        var allTypesFromBinDir = AllTypes
            .FromAssemblyInDirectory(new AssemblyFilter(HttpRuntime.BinDirectory));

        container.Register(allTypesFromBinDir
            .BasedOn<IPostRepository>()
            .WithService.FromInterface()
            .Configure(c => c.LifeStyle.Transient));
    }
}

Then in your Global.asax install your dependencies:

protected virtual void Application_Start()
{
    new WindsorContainer().Install(FromAssembly.InDirectory(new AssemblyFilter(HttpRuntime.BinDirectory)));
}
查看更多
啃猪蹄的小仙女
4楼-- · 2019-02-18 21:50

Use installers. from the global.asax you can call:

_container.Install(FromAssembly.InDirectory(new AssemblyFilter(HttpRuntime.BinDirectory, "YourNamespaceToScan*.dll")));

In your business, DA and Model projects you can then add installers to install dependancies for each:

 public class ServicesInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
               ...);
        }
    }
查看更多
淡お忘
5楼-- · 2019-02-18 22:02

You should configure the DI container in the MVC project. This is where everything comes into live. This where all the assemblies must be referenced including the data access layer of course (without referencing a concrete data access your MVC application simply cannot work). So the MVC application knows all about the other layers. Application_Start in Global.asax is a good place to configure a DI container.

查看更多
登录 后发表回答