从API控制器中的Castle Windsor容器中解析

时间:2013-12-15 03:59:42

标签: c# inversion-of-control castle-windsor factory asp.net-apicontroller

我有一个API控制器,可以触发使用构造函数依赖注入的服务。我想使用Windsor容器注入这些依赖项,但我不确定最佳实践。

这是API控制器工厂的一部分:

private readonly IWindsorContainer _container;
private readonly ServiceFactory _serviceFactory;
...
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
    Arguments args = new Arguments(new { serviceFactory = _serviceFactory });
    IHttpController controller = (IHttpController)_container.Resolve(controllerType, args);
    request.RegisterForDispose(new Release(() => _container.Release(controller)));
    return controller;
}
...

以下是服务工厂的一部分:

private readonly IWindsorContainer _container;
...
public IService Create(Type serviceType, ApiRequestModel apiRequest)
{
    Arguments args = new Arguments(new { request = apiRequest });
    return (IService)_container.Resolve(serviceType, args);
}
...

以下是API控制器的一部分:

private ServiceFactory _serviceFactory { get; set; }
...
public object Post([FromBody]ApiRequestModel request)
{
    ...
    Type serviceType = Assembly.Load("TestProject").GetType("TestClass");
    IService instance = _serviceFactory.Create(serviceType, request);
    ...
    _serviceFactory.Release(instance);
}
...

Service Factory包含Windsor容器的实例,因此将它暴露给API控制器是一个坏主意吗?如果是这样,最好的选择是什么?感谢。

1 个答案:

答案 0 :(得分:0)

我的解决方案是使用通用类型工厂设施(例如http://thesenilecoder.blogspot.com/2012/04/ioc-windsor-typedfactoryfacility-and.html

工厂只包含以下界面:

public interface IServiceFactory
{
    T Create<T>(ApiRequestModel request) where T : IService;

    void Release(IService service);
}

以下是它如何安装到容器中:

container.AddFacility<TypedFactoryFacility>();
container.Register(
    Component.For<IServiceFactory>().AsFactory(),
    Classes.FromThisAssembly().BasedOn<IService>().LifestylePerWebRequest());

将其注入API控制器并允许我创建泛型类型。在我去工厂之前,我使用反射来解析泛型类型。

Type serviceType = Assembly.Load("TestProject").GetType("TestClass");
MethodInfo factoryMethod = _serviceFactory.GetType().GetMethod("Create").MakeGenericMethod(serviceType);
IService instance = (IService)factoryMethod.Invoke(_serviceFactory, new object[] { request });