c# – web api控制器和城堡windsor生活方式
作者:互联网
在web api控制器功能中,我使用两种服务,因为它们做独立的东西,我希望它们使用不同的工作单元(事务).
所有必要的组件(工作单元,存储库)都通过带有LifestylePerWebRequest的城堡windsor注入.
据我所知,解决方案是使用LifeStyleScoped但我有两个问题:
>我希望LifeStyleScoped仅适用于这种特殊情况而不是一般情况
>我找不到如何在控制器中使用LifeStyleScoped的单个示例.
任何其他建议或代码示例将不胜感激.
编辑:我没有提到单元工作没有在控制器中明确注入.在控制器中注入两个服务,这些服务使用通过城堡windsor创建的工作单元.
public class SomeController : ApiController
{
private readonly IService _service1;
private readonly IService _service2;
public SomeController (IService service1, IService service2)
{
_service1= service1;
_service2= service2;
}
public IHttpActionResult SomeAction()
{
_service1.DoSomething();
_service2.DoSomething();
}
}
public Service : IService
{
public Service(IUnitOfWork uow) {
}
}
解决方法:
如果您在Web API应用程序中使用Castle.Windsor,您可能已经在使用IDependencyResolver,您可以将其连接起来使用Windsor自己的范围,类似于:
class WindsorDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer _container;
public WindsorDependencyResolver(IWindsorContainer container)
{
_container = container;
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public void Dispose()
{
}
}
class WindsorDependencyScope : IDependencyScope
{
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
public WindsorDependencyScope(IWindsorContainer container)
{
_container = container;
_scope = container.BeginScope();
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public void Dispose()
{
_scope.Dispose();
}
}
Web API将为每个请求创建一个新范围,并在请求完成后进行处理.因此,如果您使用这种技术,您可以取消LifestylePerWebRequest并简单地使用LifestyleScoped,从而解决了为每个组件进行两次注册的需要.
第二个挑战是:你如何获得第二个独立的工作单位?显然,所有强制和可选的控制器依赖关系都将在同一ILifetimeScope中隐式解析,因此简单地天真地声明第二个IUnitOfWork的构造函数依赖关系将不起作用.
有很多方法可以做到这一点,但是如果你准备好使用Service Locator Anti-Pattern,你可以简单地创建自己的范围,如下所示:
public class SomeController : ApiController
{
private readonly IUnitOfWork _uow;
public SomeController (IUnitOfWork uow)
{
_uow = uow;
}
public IHttpActionResult SomeAction()
{
// Get a second UoW
using (var separatelyScopedResolver = GlobalConfiguration.Configuration.DependencyResolver.BeginScope())
{
var anotherUoW = separatelyScopedResolver.GetService(typeof (IUnitOfWork));
// Do something with this UoW...
anotherUoW.Save();
}
// Do something with the default UoW...
_uow.Save();
// Et cetera...
}
}
标签:c,asp-net-web-api,castle-windsor 来源: https://codeday.me/bug/20190623/1274019.html