我阅读了这些(+,+,+和+)页面,但我无法弄清楚应该怎么做。
我有这个简单的界面和具体类型:
public interface IIdentifierGenerator {
long Generate(Type type);
long Generate<TType>(TType type);
}
public HiloIdentifierGenerator : IIdentifierGenerator { /* implementation... */ }
我创建了这个DependencyResolver
:
public class SelfHostedSimpleInjectorWebApiDependencyResolver : IDependencyResolver {
private readonly Container _container;
private readonly LifetimeScope _lifetimeScope;
public SelfHostedSimpleInjectorWebApiDependencyResolver(
Container container)
: this(container, false) {
}
private SelfHostedSimpleInjectorWebApiDependencyResolver(
Container container, bool createScope) {
_container = container;
if (createScope)
_lifetimeScope = container.BeginLifetimeScope();
}
public IDependencyScope BeginScope() {
return new SelfHostedSimpleInjectorWebApiDependencyResolver(
_container, true);
}
public object GetService(Type serviceType) {
return ((IServiceProvider)_container).GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType) {
return _container.GetAllInstances(serviceType);
}
public void Dispose() {
if (_lifetimeScope != null)
_lifetimeScope.Dispose();
}
}
我配置了我的服务器:
_config = new HttpSelfHostConfiguration("http://192.168.1.100:20000");
_config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
_config.DependencyResolver =
new SelfHostedSimpleInjectorWebApiDependencyResolver(
IoC.Wrapper.GetService<Container>());
_server = new HttpSelfHostServer(_config);
/* etc. */
这是我的控制者:
public class IdentifierController : ApiController {
private readonly IIdentifierGenerator _identifierGenerator;
public IdentifierController(IIdentifierGenerator identifierGenerator) {
_identifierGenerator = identifierGenerator;
}
public long Get(string id) {
var type = Type.GetType(id, false, true);
return type == null ? -1 : _identifierGenerator.GetIdentifier(type);
}
}
现在,当我调用action方法时,我收到此错误:
跨线程使用LifetimeScope实例是不安全的。使 确保寿命范围内的完整操作得到 在同一个线程内执行并确保LifetimeScope 实例在创建时放置在同一个线程上。部署 在ManagedThreadId 28的线程上调用,但是创建于 ID为29的线程。
我在哪里做错了?你能帮忙吗?
答案 0 :(得分:2)
Simple Injector中的Lifetime Scope生活方式旨在用于单个线程。在多个线程上运行它(甚至调用Dispose)不是线程安全的。然而,Web API自托管将创建的作用域部署在不同的线程上,甚至可以将控制器安排在与创建生命周期作用域不同的线程上运行。由于这不安全,Simple Injector会在这种情况下抛出异常。
正如我在this讨论中解释的那样,我不知道在Web API级别有一个很好的解决方案,但是当转向基于消息的架构时,问题就完全消失了,因为你可以注入{控制器中的{1}}并使用装饰器装饰该控制器,该装饰器将Lifetime范围行为添加到命令处理程序。这样,您应该使用不会创建生命周期范围的更简单的解析程序替换ICommandHandler<TCommand>
。我在讨论中解释了它,并提到了其他SO答案和博文。我知道你已经读过这篇文章,因为你已经提到了SO答案,但这是我能给你的最好的。