.net Autofac解析具有混合作用域的组件
我在asp.net中使用Autofac 2.5,我遇到了一个问题,即生命周期范围组件作为单实例组件的依赖项得到解决,从而破坏了我的线程安全。这是注册中的一个问题,但我认为Autofac将此视为违反,并将抛出异常.net Autofac解析具有混合作用域的组件,.net,dependency-injection,autofac,.net,Dependency Injection,Autofac,我在asp.net中使用Autofac 2.5,我遇到了一个问题,即生命周期范围组件作为单实例组件的依赖项得到解决,从而破坏了我的线程安全。这是注册中的一个问题,但我认为Autofac将此视为违反,并将抛出异常 private class A{} private class B { public B(A a){} } [Test] [ExpectedException()] public void SingleInsta
private class A{}
private class B
{
public B(A a){}
}
[Test]
[ExpectedException()]
public void SingleInstanceCannotResolveLifetimeDependency()
{
var builder = new ContainerBuilder();
builder.RegisterType<A>()
.InstancePerLifetimeScope();
builder.RegisterType<B>()
.SingleInstance();
using (var container = builder.Build())
{
using (var lifetime = container.BeginLifetimeScope())
{
//should throw an exception
//because B is scoped singleton but A is only scoped for the lifetime
var b = lifetime.Resolve<B>();
}
}
}
是-您需要命名子作用域,并将组件
A
与之显式关联。否则,正如您所观察到的,将在根(容器)范围中创建一个实例
谢谢,我花了一段时间才弄明白单个实例只是根生命周期范围。我用一个小的扩展方法更新了我的问题,为这些情况抛出了一个异常。如果在ResolveOperation上公开“\u activationStack”会更好,那么我可以抛出更多有用的信息。
public static class NoLifetimeResolutionAtRootScopeExtensions
{
/// <summary>
/// Prevents instances that are lifetime registration from being resolved in the root scope
/// </summary>
public static void NoLifetimeResolutionAtRootScope(this IContainer container)
{
LifetimeScopeBeginning(null, new LifetimeScopeBeginningEventArgs(container));
}
private static void LifetimeScopeBeginning(object sender, LifetimeScopeBeginningEventArgs e)
{
e.LifetimeScope.ResolveOperationBeginning += ResolveOperationBeginning;
e.LifetimeScope.ChildLifetimeScopeBeginning += LifetimeScopeBeginning;
}
private static void ResolveOperationBeginning(object sender, ResolveOperationBeginningEventArgs e)
{
e.ResolveOperation.InstanceLookupBeginning += InstanceLookupBeginning;
}
private static void InstanceLookupBeginning(object sender, InstanceLookupBeginningEventArgs e)
{
var registration = e.InstanceLookup.ComponentRegistration;
var activationScope = e.InstanceLookup.ActivationScope;
if (registration.Ownership != InstanceOwnership.ExternallyOwned
&& registration.Sharing == InstanceSharing.Shared
&& !(registration.Lifetime is RootScopeLifetime)
&& activationScope.Tag.Equals("root"))
{
//would be really nice to be able to get a resolution stack here
throw new DependencyResolutionException(string.Format(
"Cannot resolve a lifetime instance of {0} at the root scope.", registration.Target))
}
}
}
container.NoLifetimeResolutionAtRootScope();
// Replace `A` registration with:
builder.RegisterType<A>().InstancePerMatchingLifetimeScope("child");
// Replace scope creation with:
using (var lifetime = container.BeginLifetimeScope("child")) {