Question

This is probably a bit trivial, but I must be doing something wrong. I have an MVC project, where I have two projects controlled by IoC using Windsor:

  1. The MVC project
  2. A project with services

Normally I would register the services using an XML file. However, I want to register all services and interfaces automatically.

All my services is placed in my services project called LetterAmazer.Business.Services, under the namespace LetterAmazer.Business.Services.Services. My interfaces, which the services derive from, is in the namespace LetterAmazer.Business.Services.Domain .

I have tried to set it up in my Global.asax, in the following way:

private void InitializeContainer()
        {
            var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
            FilterProviders.Providers.Remove(oldProvider);

            Container.Register(Component.For<IWindsorContainer>().Instance(this.Container));
            Container.Install(new BootstrapInstaller());

            Container.Register(
                Classes.FromAssemblyInDirectory(new AssemblyFilter("LetterAmazer.Business.Services"))
                    .InNamespace("LetterAmazer.Business.Services.Services"));
            Container.Install(new WebWindsorInstaller());

            var provider = new WindsorFilterAttributeFilterProvider(this.Container);
            FilterProviders.Providers.Add(provider);

            DependencyResolver.SetResolver(new WindsorDependencyResolver(ServiceFactory.Container));
        }

        public IWindsorContainer Container
        {
            get { return ServiceFactory.Container; }
        }

But this provides several issues. First of all, it doesn't find any services when running the Classes.FromAssemblyInDirectory call. Furthermore, this wouldn't get the interfaces.

So I am basically asking how to solve this problem in a best practice way? I have 30+ services, and I want them all, so it would make sense to add them by conventation rather than hand pick.

EDIT:

The code I ended up with:

  var assembly = Assembly.LoadFrom(Server.MapPath("~/bin/LetterAmazer.Business.Services.dll")); ;
        Container.Register(
            Classes.FromAssembly(assembly)
            .InNamespace("LetterAmazer.Business.Services.Services")
            .WithServiceAllInterfaces());
Was it helpful?

Solution

I haven't used Classes.FromAssemblyInDirectory() method but I usually use FromThisAssembly() or 'FromAssemblyContaining()' methods to select assemblies. Simetimes FromAssembly("AssemblyName") is used.

I would write the following code the following way if there is no base interface for all seervices:

container.Register(
    Classes.FromAssembly("LetterAmazer.Business.Services")
        .InNamespace("LetterAmazer.Business.Services.Services")
        .WithServiceAllInterfaces());

If there is a generic interface IService<T> I would use the following registration:

container.Register(
    Classes.FromAssembly("LetterAmazer.Business.Services")
        .BasedOn(typeof(IService<>))
        .WithServiceAllInterfaces());

I'd like to add that all your services will be registered as Singletons if life style is not specified during registration.

You can find detailed information in the article Registering components by conventions from Castle Windsor website.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top