带有 WCF 的 Autofac - 嵌套生命周期问题

Autofac with WCF - Nested lifetimes problems

我有一些 WCF 服务设置被 angularjs 使用。目前我 运行 遇到了一个我正在努力解决的问题。调用 WCF 服务时,我不断收到以下错误消息。任何有关如何解决此问题的指示将不胜感激。更详细的错误信息可以在底部找到

Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed.

编辑:当我在 global.asax Application_BeginReques() 中构建容器时似乎也有效,因此不仅 Application_Start。不知道为什么,但至少这比以前好......但是我以前时不时会发生这个错误所以我不相信这个丑陋的解决方法

这是我的global.asax

        ..
        ..

    protected void Application_Start(object sender, EventArgs e)
    {
        var containerBuilder = new IoC();

        // Register your service implementations.
        containerBuilder.Builder.RegisterType<Konstrukt.SL.Services.GetBudgetData>().Named<object>("GetBudgetDataService");
        containerBuilder.Builder.RegisterType<Konstrukt.SL.Services.GetReferenceData>().Named<object>("GetReferenceDataService");
        containerBuilder.Builder.RegisterType<Konstrukt.SL.Services.UpdateBudgetData>().Named<object>("UpdateBudgetDataService");
        ..
        ..
        containerBuilder.Builder.RegisterType<Konstrukt.SL.Services.DimValue>().Named<object>("DimValueService");
        containerBuilder.Builder.RegisterType<Konstrukt.SL.Services.DisplayNameMapping>().Named<object>("DisplayNameMappingService");
        ..
        ..

        // use only one context object per scope/request
        containerBuilder.Builder.RegisterType<Konstrukt.DAL.KonstruktEntities>().InstancePerLifetimeScope();

        AutofacHostFactory.Container = containerBuilder.Builder.Build();
    }

这是我的 IoC class,它注册了所有接口

public class IoC
{
    private ContainerBuilder _builder;
    public ContainerBuilder Builder 
    {
        get 
        {
            if (_builder == null)
            {
                _builder = new ContainerBuilder();

                _builder.RegisterType<BL.App.App>().As<BL.App.IApp>();
                _builder.RegisterType<BL.AppConfig.AppConfig>().As<BL.AppConfig.IAppConfig>();
                _builder.RegisterType<BL.AppConfig.ComponentSetting>().As<BL.AppConfig.IComponentSetting>();
                _builder.RegisterType<BL.AppConfig.Component>().As<BL.AppConfig.IComponent>();
                _builder.RegisterType<BL.AppConfig.AppSetting>().As<BL.AppConfig.IAppSetting>();
                _builder.RegisterType<BL.AppConfig.AppDataSet>().As<BL.AppConfig.IAppDataSet>();
                _builder.RegisterType<BL.AppConfig.AttributeData>().As<BL.AppConfig.IAttributeData>();
                _builder.RegisterType<BL.AppConfig.Constants>().As<BL.AppConfig.IConstants>();
                ..
                ..
                _builder.RegisterType<BL.DimensionData.DisplayNameMapping>().As<BL.DimensionData.IDisplayNameMapping>();
                ..
                ..
                //DAL registrations, etc
                ..
                ..

            }
            return _builder;
        }
        set { _builder = value; }
    }

}

示例 WCF 服务实现

public class DimValue : IDimValue
{
    private BL.DimensionData.IDimValue _dimValue;
    public DimValue(ILifetimeScope container, BL.DimensionData.IDimValue dimValue)
    {
        AutofacHostFactory.Container = container;
        _dimValue = dimValue;
    }

    public IList<Shared.Poco.DimValue> GetDimValueList(int budgetId, string dimensionFilterJSON, string userId)
    {
        Dictionary<Shared.Poco.Dimension, List<string>> dimensionFilters = null;
        Shared.Poco.User user = new Shared.Poco.User { UserId = userId };
        IList<Shared.Poco.DimValue> list = new List<Shared.Poco.DimValue>();

        using (var scope = AutofacHostFactory.Container.BeginLifetimeScope())
        {
            dimensionFilters = JsonConvert.DeserializeObject<Dictionary<Shared.Poco.Dimension, List<string>>>(dimensionFilterJSON);

            foreach (KeyValuePair<Shared.Poco.Dimension, List<string>> kvp in dimensionFilters)
            {
                foreach (Shared.Poco.DimValue dv in _dimValue.GetDimValueList(budgetId, kvp.Key, kvp.Value, user))
                {
                    list.Add(dv);
                }
            }
        }
        return list;
    }
}

[ServiceContract]
    public interface IDimValue
    {
        [OperationContract]
        [WebInvoke(Method = "GET",
                    RequestFormat = WebMessageFormat.Json,
                    ResponseFormat = WebMessageFormat.Json,
                    BodyStyle = WebMessageBodyStyle.Bare,
                    UriTemplate = "GetDimValueList?budgetId={budgetId}&dimensionFilterJSON={dimensionFilterJSON}&userId={userId}")]
        IList<Shared.Poco.DimValue> GetDimValueList(int budgetId, string dimensionFilterJSON, string userId);
    }

服务标记

<%@ ServiceHost Language="C#" 
Debug="true" 
Service="DimValueService"
Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf" 
CodeBehind="DimValue.svc.cs" %>

调用 DimValue 时的详细错误。svc/GetDimValueList

The server encountered an error processing the request. The exception message is 'Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed.'. See server logs for more details. The exception stack trace is: at Autofac.Core.Lifetime.LifetimeScope.CheckNotDisposed() at Autofac.Core.Lifetime.LifetimeScope.BeginLifetimeScope(Object tag) at Autofac.Core.Lifetime.LifetimeScope.BeginLifetimeScope() at Autofac.Integration.Wcf.AutofacInstanceContext..ctor(ILifetimeScope container) at Autofac.Integration.Wcf.AutofacInstanceProvider.GetInstance(InstanceContext instanceContext, Message message) at System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance(InstanceContext instanceContext, Message request) at System.ServiceModel.InstanceContext.GetServiceInstance(Message message) at System.ServiceModel.Dispatcher.InstanceBehavior.EnsureServiceInstance(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

问题是您的服务实现采用子生命周期范围,然后更改全局生命周期范围。

进入您的服务实现的 ILifetimeScope 是特定于服务实现保险的容器的子项,它会在服务实现被处置时被处置。

但是服务实现正在将全局容器 - AutofacHostFactory.Container - 切换为子生命周期范围。因此,当服务实例消失时......现在,全局容器也消失了。

停止从服务设置容器,你应该没问题。

一般来说,在应用程序启动后,你真的不应该弄乱全局根容器