How do I connect the various pieces of my Web API Castle Windsor DI code?

别等时光非礼了梦想. 提交于 2019-12-01 08:05:25
Adam Connelly

Don't want to repeat everything again, so just check out my answer on How do I get Web API / Castle Windsor to recognize a Controller?.

As another note - I would advise against doing anything in your repository constructors if you can help it. The reason I say this is that the constructors get called as Windsor is trying to instantiate the correct instance of your repository. What this means is that if any kind of error occurs, it happens as WebApi is trying to create the controller. This can make it a bit tricky to track down the problem sometimes, and also ends up hiding the real issues under tons of layers of exceptions.

You should not mix installation vs resolving. IOW your should not have

kernel.AddFacility<TypedFactoryFacility>();

in the WindsorControllerFactory

But the generic container configuration such registering TypedFactoryFacility should be executed in an installer called as earlier as possible.

In order to drive installer execution, you should use an Installer factory

public class YourInstallerFactory : InstallerFactory
{
    public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes)
    {
        var windsorInfrastructureInstaller = installerTypes.FirstOrDefault(it => it == typeof(WindsorInfrastructureInstaller));

        var retVal = new List<Type>();
        retVal.Add(windsorInfrastructureInstaller);
        retVal.AddRange(installerTypes
            .Where(it =>
                typeof(IWindsorInstaller).IsAssignableFrom(it) &&
                !retVal.Contains(it)
                ));

        return retVal;
    }
}

Where windsorInfrastructureInstaller will be somenthing like this

public class WindsorInfrastructureInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        // Resolvers
        //container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel));

        // TypedFactoryFacility
        container.AddFacility<TypedFactoryFacility>();
    }
}

In your global.asax you'll create&use you installer factory as following

 var installerFactory = new YourInstallerFactory();
 container.Install(FromAssembly.This(installerFactory));

Your "FrontEnd"(for example the mvc/webapi) project has a folder containing all installers(WindsorInfrastructureInstaller will be one of those) and the installer factory as well or at least that's the way I'm use to organize my solution.

In answer to my own question, I would simply say: There are no shortcakes! Without stopping go or further ado, go here and get this book. Resign yourself to take the time necessary to read it carefully.

So I'm not the only one; here's a quote from Jeff Beck, who wrote that book's foreword: "Often those who start using DI quickly find themselves lost in a sea of confusion."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!