gpt4 book ai didi

c# - 制作自定义 IoC - 如何实现具有作用域的 DI?

转载 作者:行者123 更新时间:2023-11-30 21:20:40 26 4
gpt4 key购买 nike

我正在为自己的学习/成长编写一个 IoC 容器。通常我会写如下内容:

using(DisposableObject dispObj = new DisposableObject())
{
UserRepository users = new UserRepository(dispObj);

// Do stuff with user.
}

将转向:

using(IDisposableObject dispObj = Container.Resolve<IDisposableObject>())
{
IUserRepository users = Container.Resolve<IUserRepository>();

// Do stuff with user.
}

我如何抽象 DisposableObject,使其成为 using 中唯一使用的实例使用 IoC 时的范围?我正在尝试弄清楚 Autofac 是如何做到的,但我并不完全确定。

编辑:当一个对象被实例化为 using作用域,所有解析该类型的调用(在本例中为 IDisposableObject )都应返回作用域变量,而不是新实例。同样重要的是,在 using 之后声明,和另一个 Resolve<IDisposableObject>被调用时,它返回一个新的实例。

最佳答案

以这种方式使用一次性对象时要记住的是,容器中的引用也会被丢弃,因此理想情况下,当您通过 Resolve<> 返回一个实例时,它需要每次都返回一个新实例。

您需要做的是,在向您的容器注册类型时,允许它指定一种行为,共享(单例)或非共享,例如:

Container.RegisterType<IDisposableObject>(CreationPolicy.NonShared);

using (var disposable = Container.Resolve<IDisposableObject>()) {

}

上面的方法适用于 NonShared 实例,因为每次都会创建一个新实例,所以我们可以安全地处理它。如果您尝试使用 CreationPolicy = Shared 执行上述操作,则单例将被丢弃,因此将来的访问可能会导致 ObjectDisposedException。

通过构建此行为,您可以通过传递 CreationPolicy = Shared 来创建 Singleton 实例,例如:

Container.RegisterType<IUserRepository>(CreationPolicy.Shared);

using (var disposable = Container.Resolve<IDisposableObject>()) {
var userRepository = Container.Resolve<IUserRepository>();
// only one instance of user repository is created and persisted by the container.
}

希望对您有所帮助?

如果您以前使用过 MEF,那么这个术语可能很熟悉。

编辑:因此,我的理解是您想要执行以下操作:

using (var repository = Container.Resolve<IUserRepository>())
{
var other = Container.Resolve<IUserRepository>();
// should resolve to the same instance.
}

您需要找到某种方法来监控容器中的一次性元素。也许引入额外的创建策略 SharedScope,例如:

Container.Register<IUserRepository, UserRepository>(CreationPolicy.SharedScope);

现在,当您使用容器解析类型时,您需要确定项目的 CreationPolicy。如果该项目是 SharedScope,并且尚未创建,则创建它的一个实例并返回。

如果您解析实例并且它已经被创建,则返回现有实例。

当对该项目调用 Dispose 时,您需要一些方法来回调容器以删除该实例。

编辑二:

好吧,没有一种简单的方法可以解决这个问题。我能想到的唯一方法是你引入另一个接口(interface):

public interface IMonitoredDisposable : IDisposable
{
bool IsDisposed { get; set; }
}

释放对象时,确保它设置了 IsDisposed 属性。然后您可以从您的容器中监控该属性吗?

关于c# - 制作自定义 IoC - 如何实现具有作用域的 DI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3151180/

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