Avoid singleton repository (DryIoc) when using dependency injection(使用依赖项注入时避免使用单一存储库(DryIoc)
问题描述
我最近创建了一个解决方案,我想我应该尝试一下DryIoC容器来处理依赖项注入。现在,与我使用的许多其他DI解决方案一样,对象重用的默认作用域是瞬时。然而,这似乎给我正在使用的存储库模式的实现带来了问题,因为如果引用的类实现了IDisposable,则DryIoC(和许多其他解决方案)不能将绑定注册为临时绑定。因此,我暂时求助于向Reuse.Singleton注册我的存储库。这对我来说绝对是一种代码气味,所以我希望有人能给我一些如何避免这种情况的建议--例如,可能是我在创建存储库方面做得不好。
以下是我用来创建IOC容器的代码:
private static Container ConstructNewContainer()
{
var container = new Container(Rules.Default);
container.Register(Made.Of(() => SettingsFactory.CreateSettings()));
container.Register<IRepository<tblMailMessage>, MailMessageRepository>(Reuse.Singleton);
container.Register<IRepository<ProcessedMailMessages>, ProcessedMailMessageRepository>(Reuse.Singleton);
container.Register<IParser, EmailParser>();
container.Register<IMonitor, DatabaseMonitor>();
return container;
}
...和一个存储库实现示例:
public interface IRepository<T>
{
void Insert(T objectToInsert);
void Delete(int id);
void Update(T objectToUpdate);
void Save();
T GetById(long id);
IEnumerable<T> Get();
T Last();
bool Exists(int id);
}
public class MailMessageRepository : IRepository<tblMailMessage>, IDisposable
{
private bool _disposed;
private readonly CoreDataModel _model;
public MailMessageRepository()
{
_model = new CoreDataModel();
}
public void Delete(int id)
{
var objectToDelete = _model.tblMailMessages.Find(id);
if (objectToDelete != null) _model.tblMailMessages.Remove(objectToDelete);
}
public void Update(tblMailMessage objectToUpdate) => _model.Entry(objectToUpdate).State = EntityState.Modified;
public void Save() => _model.SaveChanges();
public IEnumerable<tblMailMessage> Get() => _model.tblMailMessages.ToList();
public tblMailMessage Last() => _model.tblMailMessages.OrderByDescending(x => x.DateSubmitted).FirstOrDefault();
public bool Exists(int id) => _model.tblMailMessages.SingleOrDefault(x => x.MailMessageID == id) != null;
public void Insert(tblMailMessage objectToInsert) => _model.tblMailMessages.Add(objectToInsert);
public tblMailMessage GetById(long id) => _model.tblMailMessages.SingleOrDefault(x => x.MailMessageID == id);
#region Dispose
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (!disposing)
{
_model.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
推荐答案
根据the documentation,您有3个选择:
不允许注册一次性临时服务。默认DryIoc行为。
container.Register<X>(); // will throw exception
允许注册一次性暂态,但将处置服务的责任委派给容器用户。
container.Register<X>(setup: Setup.With(allowDisposableTransient: true)); // or allow globally for all container registrations: var container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient()); container.Register<X>(); // works, but dispose is up to User
在其所有者重用作用域(如果有)中跟踪(存储)可释放瞬时依赖项,或在当前打开作用域(如果有)中跟踪已解析的可释放瞬时依赖项。
container.Register<X>(setup: Setup.With(trackDisposableTransient: true)); // or track globally for all container registrations: var container = new Container(rules => rules.WithTrackingDisposableTransients()); // will be tracked in XUser parent in singleton scope and disposed with container as all singletons container.Register<XUser>(Reuse.Singleton); container.Register<X>(); // or tracking in open scope using (var scope = container.OpenScope()) scope.Resolve<X>; // will be disposed on exiting of using block
正如您在上面看到的,默认行为要求您在使用临时生活方式时显式处置。
但他们遗漏了第四个选项,即寻找另一个DI容器。我从来没有使用过DryIoC,但这似乎太让人担心了,因为你不必使用其他容器。通常,选择正确的生存期决定了何时处置实例。
这篇关于使用依赖项注入时避免使用单一存储库(DryIoc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用依赖项注入时避免使用单一存储库(DryIoc


- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- 输入按键事件处理程序 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- WebMatrix WebSecurity PasswordSalt 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 如何用自己压缩一个 IEnumerable 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01