zcz527 / autofac

Automatically exported from code.google.com/p/autofac
Other
0 stars 0 forks source link

Configured Nested Containers Lose LimitType on Component Registrations - Affects WCF Service Resolution #365

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create a simple WCF service
2. Mark it with [AspNetCompatibilityRequirements(RequirementsMode = 
AspNetCompatibilityRequirementsMode.Required)]
3. Resolve the service instances using Autofac.Wcf
4. In global.asax put the following
protected void Application_Start(object sender, EventArgs e) {
            var builder = new ContainerBuilder();
...
_container = builder.Build();
_containerProvider = new ContainerProvider(_container); //for per-request
//Create a special scope for WCF services
_wcfRootLifetimeScope = _container.BeginLifetimeScope(innerBuilder => {});// 
the issue is here
AutofacHostFactory.Container = _wcfRootLifetimeScope;
}

What is the expected output? What do you see instead?
expect: The WCF service should be activated successfully
result:

[InvalidOperationException: The service cannot be activated because it does not 
support ASP.NET compatibility. ASP.NET compatibility is enabled for this 
application. Turn off ASP.NET compatibility mode in the web.config or add the 
AspNetCompatibilityRequirements attribute to the service type with 
RequirementsMode setting as 'Allowed' or 'Required'.]
   System.ServiceModel.Activation.HostedAspNetEnvironment.ValidateCompatibilityRequirements(AspNetCompatibilityRequirementsMode compatibilityMode) +197944
   System.ServiceModel.Description.DispatcherBuilder.ValidateDescription(ServiceDescription description, ServiceHostBase serviceHost) +391
   System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +334
   System.ServiceModel.ServiceHostBase.InitializeRuntime() +82
   System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +64
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +789
   System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +255
   System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +1172

[ServiceActivationException: The service '/autofacService.svc' cannot be 
activated due to an exception during compilation.  The exception message is: 
The service cannot be activated because it does not support ASP.NET 
compatibility. ASP.NET compatibility is enabled for this application. Turn off 
ASP.NET compatibility mode in the web.config or add the 
AspNetCompatibilityRequirements attribute to the service type with 
RequirementsMode setting as 'Allowed' or 'Required'..]
   System.Runtime.AsyncResult.End(IAsyncResult result) +901424
   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +178702
   System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +136

What version of Autofac are you using? On what version of .NET/Silverlight?
Autofac.2.6.1.841, Autofac.Wcf.2.6.1.841, Autofac.Web.2.6.1.841
.net 4.0

Please provide any additional information below.

If we modify the mentioned code to:
    _container = builder.Build();
    _containerProvider = new ContainerProvider(_container); //for per-request
    //Create a special scope for WCF services
     _wcfRootLifetimeScope = _container.BeginLifetimeScope();
    AutofacHostFactory.Container = _wcfRootLifetimeScope;
the problem disappears.

The purpose of the code is to override the default component configuration for 
my WCF services.

Original issue reported on code.google.com by perekrestov.stas on 13 May 2012 at 1:24

GoogleCodeExporter commented 8 years ago
Here is a solution that shows the mentioned behavior

Original comment by perekrestov.stas on 13 May 2012 at 2:16

Attachments:

GoogleCodeExporter commented 8 years ago
The workaround for this issue:

Register WCF services 
_container.BeginLifetimeScope(innerBuilder => {
//put all necessary registrations overrides here and register wcf services
...
innerBuilder.RegisterType<AutofacService>().As<IAutofacService>().UseWcfSafeRele
ase();
})

Original comment by perekrestov.stas on 14 May 2012 at 9:44

GoogleCodeExporter commented 8 years ago

Original comment by travis.illig on 21 Sep 2012 at 4:35

GoogleCodeExporter commented 8 years ago
Some research shows that the difference is that the configured lifetime scope 
somehow loses the strong type of the registered service.

More specifically, when
AutofacHostFactory.Container = container
or when
AutofacHostFactory.Container = container.BeginLifetimeScope()
then in the AutofacHostFactory.CreateServiceHost method, the component registry 
locates the registration for the WCF "IAutofacService" and finds that the 
"limit type" (the type it'll be resolved to) is the concrete "AutofacService" 
type.

However, when there's a configuration action, the 
AutofacHostFactory.CreateServiceHost method looks at the registration for WCF 
"IAutofacService" and thinks the "limit type" is System.Object - no longer the 
actual AutofacService type.

The located type is how WCF generates the service description - using the 
attributes off the located type to determine compatibility requirements.

This will also affect the way Autofac determines if the service is a singleton 
- it uses that type to look for lifetime-related attributes.

I'll have to look into why it's losing the concrete limit type when there's a 
configuration action, but that's not specific to WCF - that will have something 
to do with the way nested lifetime scopes are created so it'll be a Core change 
and probably not a five-minute-fix.

I've updated the issue description/categorization to reflect the actual source 
of the problem.

Original comment by travis.illig on 7 Dec 2012 at 5:42

GoogleCodeExporter commented 8 years ago
Actually... it WAS a five-minute-fix. Well, five minutes of coding, more than 
that for tracing it down.

I'll commit the fix shortly. It'll be in the 3.0 final release.

Original comment by travis.illig on 7 Dec 2012 at 6:25

GoogleCodeExporter commented 8 years ago
This issue was closed by revision 83d0dcbd3a31.

Original comment by travis.illig on 7 Dec 2012 at 6:42