我最近创建了一个解决方案,并想尝试使用 DryIoC 容器来处理依赖项注入(inject)。现在,与我使用过的许多其他 DI 解决方案一样,对象重用的默认范围是 transient。然而,这似乎对我正在使用的存储库模式的实现造成了问题,因为如果引用的类实现了 IDisposable,DryIoC(和许多其他解决方案)无法将绑定(bind)注册为 transient 。因此,我暂时求助于使用 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
}
最佳答案
文档 here 解释了为什么一次性 transient 是问题所在,以及为什么以这种方式选择 DryIoc 默认行为。基本上,这种行为是为了将问题告知您,而不是默默地接受它。
关于其他容器,没有强烈偏好特定的一次性 transient 处理。这是与 Microsoft.Extensions.DependencyInjection 相关的讨论,有 Autofac、StructureMap 和其他容器开发人员参与。
顺便说一句,DryIoc 错误消息包含如何选择加入问题的提示。
关于c# - 使用依赖注入(inject)时避免单例存储库(DryIoc),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46424751/