Note that there are some explanatory texts on larger screens.

plurals
  1. POAutofac resolves components with mixed scope
    text
    copied!<p>I'm using Autofac 2.5 in asp.net and I'm having an issue where lifetime scope components are getting resolved as dependencies of single instance components thus destroying my thread safety. This is a problem with the registrations but I thought Autofac viewed this as a violation and would throw an exception.</p> <pre><code> private class A{} private class B { public B(A a){} } [Test] [ExpectedException()] public void SingleInstanceCannotResolveLifetimeDependency() { var builder = new ContainerBuilder(); builder.RegisterType&lt;A&gt;() .InstancePerLifetimeScope(); builder.RegisterType&lt;B&gt;() .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&lt;B&gt;(); } } } </code></pre> <p>Is there a way to have Autofac throw a Dependency resolution exception if this happens?</p> <p><strong>UPDATE</strong> Even though this is the correct behavior for Autofac - SingleInstance is just Root lifetime scoped - it can be potentially dangerous in a web environment. Making sure that all of your developers get the correct registrations can be a pain. Here is a small extension method for Autofac that checks an instance lookup to make sure that lifetime scoped instances do not get resolved in the root scope. I know it has helped us weed lifecycle issues out of our web project.</p> <pre><code> public static class NoLifetimeResolutionAtRootScopeExtensions { /// &lt;summary&gt; /// Prevents instances that are lifetime registration from being resolved in the root scope /// &lt;/summary&gt; 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 &amp;&amp; registration.Sharing == InstanceSharing.Shared &amp;&amp; !(registration.Lifetime is RootScopeLifetime) &amp;&amp; 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)) } } } </code></pre> <p>Just apply this when you create your container and you will get exceptions thrown when lifetime scoped services are resolved in the root scope.</p> <pre><code>container.NoLifetimeResolutionAtRootScope(); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload