- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为什么dynamic instantiation的Autofac隐式关系类型会考虑生存期范围?
关于这个主题的文档指出:
使用此关系类型会尊重生命周期范围。如果将对象注册为InstancePerDependency()
并多次调用Func<B>
,则每次都会获得一个新实例。但是,如果将一个对象注册为SingleInstance()
并调用Func<B>
多次解析该对象,则每次都将获得相同的对象实例。
文档还声称此隐式关系类型的目的是出于以下两个目的:
在运行时解析实例,而不依赖于Autofac本身
解决给定服务的多个实例
Delayed instantiation(Lazy<B>
)以我理解的方式实现了目的1,并且我同意其设计要尊重生命周期的范围。我不理解或不同意Autofac针对Func<B>
的设计,因为无法使用动态实例化隐式关系类型来实现目标2。
要解决此问题并实际完成#2,我们使用与注册Func<B>
和闭包相同的工厂方法手动注册B
:
void RegisterDependencies(ContainerBuilder builder)
{
builder.Register<B>(bFactory).InstancePerLifetimeScope();
builder.Register<Func<B>>(context => () => bFactory(context)).SingleInstance();
B bFactory(IComponentContext context) => new B(context.Resolve<A>(), ...);
}
最佳答案
知道Func<B>
基本上是包装在非Autofac特定对象中的myCurrentLifetimeScope.Resolve<B>
的“捷径”,它可能有助于扭转这个问题,并询问为什么Func<B>
不尊重生命周期范围,以及其后果是什么如果没有的话。
利用生命周期作用域的绝大多数应用程序都是用来隔离工作单元的。例如,具有每个请求生存期范围的Web应用程序。有很多很好的理由说明为什么这是一个有趣的模式,例如只能创建给定请求所需的资源,然后在请求完成后清理它们-仅使用所需的内存。
鉴于此,通常来说,生存期范围很有趣,即使对于跟踪和清理分配的资源而言,这只是一种不错的方式。
现在,假设您已连接到某个Web服务或诸如此类的东西。也许这是WCF服务。关于WCF服务客户端,您可能会记住一些事情:
一旦通道出现故障,客户就一文不值。您不能只创建一个客户端,因为如果该服务使您的频道出现故障,则必须丢弃该客户端实例并创建一个新的客户端实例。
完成后,您需要处置客户端。如果您不这样做,他们可以保持渠道开放并消耗资源。
鉴于此,Func<IServiceClient>
的各种关系变得非常有趣。
假设您有一个MVC控制器。这是一种伪代码,我不会通过编译器运行它。
public class MyController : Controller
{
private readonly Func<IServiceClient> clientFactory;
public MyController(Func<IServiceClient> clientFactory)
{
this._clientFactory = clientFactory;
}
public string GetSomethingReallyCool()
{
var retryCount = 0;
while(retryCount < 5)
{
var client = this._clientFactory();
try
{
return client.GetSomethingCool();
}
catch
{
retryCount++;
}
}
return "We failed to get the cool data.";
}
}
Func<IServiceClient>
函数动态创建WCF服务客户端,以在需要时使用。
Func<IServiceClient>
函数动态创建WCF服务客户端,以在需要时使用。
var builder = new ContainerBuilder();
builder.RegisterType<Alpha>();
var container = builder.Build();
using(var scope = container.BeginLifetimeScope(b => b.RegisterType<Beta>())
{
var f = scope.Resolve<Func<Beta>>();
// f is a Func<Beta> - call it, and you should get a B.
// If Func<Beta> doesn't respect lifetime scopes, what
// does this yield?
var beta = f();
}
Func<B>
行为的唯一逻辑方法是服从生命周期范围。如果没有,那就行不通了。
关于c# - 为什么Autofac的用于动态实例化的隐式关系类型(Func <B>)遵守生存期范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58330487/
我是一名优秀的程序员,十分优秀!