1

I have one solution which has two projects: MVC and Business

From Castle Windsor: Register components across multiple projects in solution I could tell that all plumbing should be in the MVC layer, so I created an IoC container (in MVC) as such:

public static class IocContainer
{
    private static IWindsorContainer _container;

    public static void Setup()
    {
        _container = new WindsorContainer().Install(FromAssembly.This());
    }

    public static T Resolve<T>()
    {
        return _container.Resolve<T>();
    }
}

I also created an installer in the MVC project:

public class BusinessLogicInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<IBusinessFacade>()
            .ImplementedBy<BusinessFacade>()
            .LifestylePerWebRequest());
    }
}

Since the intaller knows about the concrete BusinessFacade type, MVC depends on the Business layer (where the BusinessFacade class resides).

Because i also want to use DI in the business layer, how would I access the IoC container from Business project, without creating a cyclic dependency with MVC and Business ?

Community
  • 1
  • 1
Kenci
  • 4,794
  • 15
  • 64
  • 108
  • I usually use the structuremap for IoC, but if you try to make your business depend of the object conainer, I think the windsor container will resolve it with the self instance. – Felipe Oriani Jul 29 '15 at 16:58

1 Answers1

1

Look in all assemblies in the bin folder at application start for types that implement IWindsorInstaller, and run their install method, passing in an application-level instance of the container (in this case that's your private container in your container wrapper class).

You generally should not be manually resolving and should wire up your application to automatically inject your controllers. If you have to manually resolve, do it once per request at the controller level.

If you resolve manually all over your code, you are using the service locator pattern, which is bad.

moarboilerplate
  • 1,633
  • 9
  • 23
  • Thanks for the answer. How do you make Windsor Castle look in all assemblies for types that implement IWindosrInstaller? – Kenci Jul 29 '15 at 18:35
  • `_container.Install(FromAssembly.InDirectory(new AssemblyFilter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))));` should work for you. – moarboilerplate Jul 29 '15 at 18:47
  • What I did so far was to move the BusinessLogicInstaller from the MVC project to the Business project. Also, I created a seperate project for interfaces, which holds the IBusinessFacade interface, and which is referenced by both the MVC project and the Business project. I figured this way I could make use of the IoC container from the Business project, since the MVC project does not need a reference to Business anymore. However, when trying to resolve IBusinessFacade, i get the following error: Additional information: No component for supporting the service Interfaces.IBusinessFacade was foun. – Kenci Jul 29 '15 at 18:56
  • Do not call the container from Business. – moarboilerplate Jul 29 '15 at 19:00
  • How do I use DI from Business then (maybe I misunderstood the whole concept)? – Kenci Jul 29 '15 at 19:01
  • 1
    The following code resolves without errors, however the assembly name is hardcoded: _container = new WindsorContainer().Install(FromAssembly.Instance(Assembly.Load("Business"))); - I thought that I could use DI from the Business layer. What if I wanted to access a repository from there, how should the concrete repository class be resolved? – Kenci Jul 29 '15 at 19:16
  • @Kenci You should have one container only, which is in your MVC layer. When the application starts, do the installing, once. The code I posted looks at all the assemblies in your bin folder and calls `Install()` . The business layer should expose services and objects that are dependencies of your controllers. Your business installer should wire up your business interfaces to business implementations. So you have a controller that takes in some IBusinessService in its constructor, which might have a method like GetABusinessObject that returns a BusinessObject. You resolve the controller only. – moarboilerplate Jul 29 '15 at 21:19