gpt4 book ai didi

asp.net - 具有 autofac、webforms 和 ServiceLocator 的生命周期范围

转载 作者:行者123 更新时间:2023-12-02 13:55:02 24 4
gpt4 key购买 nike

在旧版 Asp.NET Webforms 应用程序中,我尝试注入(inject)一些 IOC。

我不会详细介绍,但对于这个,我认为 ServiceLocator 是完成这项工作的一个很好的工具。我知道服务定位器是一种反模式;o)

根据文档https://github.com/autofac/Autofac/wiki/Common-Service-Locator ServiceLocator 配置如下:

var container = builder.Build();
var csl = new AutofacServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => csl);

问题在于 LoacatorProvider 是使用根容器设置的。因此,生命周期管理并不活跃。

我正在想办法解决这个问题

因为 ServiceLocator.SetLocatorProvider 采用委托(delegate)作为参数,并且因为每次调用 ServiceLocator.Current 时都会调用该委托(delegate),所以为什么不为每个请求提供 AutofacServiceLocator 的实例。

public class Global : HttpApplication, IContainerProviderAccessor
{
// Provider that holds the application container.
static IContainerProvider _containerProvider;

void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);

_containerProvider = new ContainerProvider(AutoFacBootstrapper.CreateContainer());

ServiceLocator.SetLocatorProvider(() =>
{
AutofacServiceLocator asl = HttpContext.Current.Items["AutofacServiceLocator"] as AutofacServiceLocator;
if (asl == null)
{
var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
var cp = cpa.ContainerProvider.RequestLifetime;
asl = new AutofacServiceLocator(cp);

HttpContext.Current.Items["AutofacServiceLocator"] = asl;
}
return asl;
});
}

public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
}

这段代码似乎可以工作。 IDisposable 对象在请求结束时被释放。 InstancePerRequest配置没问题。

此实现有任何问题(性能、内存...)吗?

最佳答案

如果对其他人有帮助,以下是我如何将其实现为请求处理程序。

这是我的 Startup.cs:

public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();

// ...
IContainer container = ConfigureAutofac(config);

// This should be the first middleware added to the IAppBuilder.
app.UseAutofacMiddleware(container);

// Make sure the Autofac lifetime scope is passed to Web API.
app.UseAutofacWebApi(config);

app.UseWebApi(config);

config.MessageHandlers.Add(new ServiceLocatorHandler());
}
}

我将在下面显示 ServiceLocatorHandler.cs

为了完整性,这是我的 ConfigureAutofac 函数:

    private IContainer ConfigureAutofac(HttpConfiguration config)
{
var builder = new ContainerBuilder();
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
builder.RegisterAssemblyModules(assemblies.ToArray());

// Register Web API classes
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(config);
builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);

// Register the modules
// ...

// Create the container
var container = builder.Build();

// Hook up the Web API dependency resolver
var resolver = new AutofacWebApiDependencyResolver(container);
config.DependencyResolver = resolver;

// ...
ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container));

return container;
}

最后,这是处理程序:

public class ServiceLocatorHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var properties = request.Properties;
var scope = properties["MS_DependencyScope"];
AutofacWebApiDependencyScope dependency_scope = scope as AutofacWebApiDependencyScope;
if (dependency_scope != null && dependency_scope.LifetimeScope != null)
{
AutofacWebApiDependencyResolver resolver = new AutofacWebApiDependencyResolver(dependency_scope.LifetimeScope);
AutofacServiceLocator asl = new AutofacServiceLocator(resolver.Container);
ServiceLocator.SetLocatorProvider(() => asl);
}
return base.SendAsync(request, cancellationToken);
}
}

在我的用例中,我有一个第三方库,它使用 IoC 通过存储库模式解析 DBContext 实现。

该库在使用其他 DI 容器的其他环境中使用,当将其与默认的 AutofacServiceLocator 根设置一起使用时,我要么会看到旧数据的 EF 缓存问题,要么会因为新上下文而出现写入失败在对象添加和提交之间创建。

非常感谢OP帮助我们解决这个问题。

关于asp.net - 具有 autofac、webforms 和 ServiceLocator 的生命周期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24999635/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com