C# Unity WebApi DbContext在使用InjectionConstructor时被释放,但在没有它的情况下可以正常工作
Repository,OrderRequestRepository.csC# Unity WebApi DbContext在使用InjectionConstructor时被释放,但在没有它的情况下可以正常工作,c#,asp.net-web-api,unity-container,dispose,dbcontext,C#,Asp.net Web Api,Unity Container,Dispose,Dbcontext,Repository,OrderRequestRepository.cs public OrderRequestRepository(IntranetApplicationsContext context, ILogger logger) { _context = context; _logger = logger; } ...CRUD Methods public void Dispose() { Dispose
public OrderRequestRepository(IntranetApplicationsContext context, ILogger logger)
{
_context = context;
_logger = logger;
}
...CRUD Methods
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_context.Dispose();
}
GC.SuppressFinalize(this);
}
Unity.WebApi UnityConfig.cs
container.RegisterType<IOrderRequestRepository, OrderRequestRepository>(new InjectionConstructor(new IntranetApplicationsContext() , new ElmahLogger()));
container.RegisterType(新的InjectionConstructor(新的intranetapplicationcontext(),新的ElmahLogger());
在UnityConfig.cs中的上述行中,对api的第一次调用起作用,第二次调用失败,出现错误:
操作无法完成,因为DbContext已被释放。
如果我注释掉了_context.Dispose()行,那么它就可以工作了,这很好,因为垃圾收集可以帮我清理,但理想情况下我希望自己管理它
或者,如果我在UnityConfig.cs中使用下面的行,而不使用InjectionConstructor,那么它也可以正常工作
container.RegisterType<ILogger, ElmahLogger>();
container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
container.RegisterType();
container.RegisterType();
但是我想使用InjectionConstructor,因为我想向OrderRequestRepository构造函数添加另一个参数并管理处置。关于为什么两者都会导致错误,有什么建议吗
更新
按照Steven的建议,我删除了IDisposable代码,因为
container.RegisterType<IOrderRequestRepository, OrderRequestRepository> (new InjectionConstructor(new IntranetApplicationsContext(), new ElmahLogger()));
container.RegisterType(新的InjectionConstructor(新的intranetapplicationcontext(),新的ElmahLogger());
使用EF进行读取是可行的,但有趣的是,当我尝试编辑时,会出现以下错误:
附加类型为的实体
“IntranetApplications.Infrastructure.Models.OrderRequest”失败
因为相同类型的另一个实体已具有相同的主实体
键值。使用“附加”方法或设置时可能会发生这种情况
实体的状态为“未更改”或“已修改”,如果实体处于
该图形具有冲突的键值。这可能是因为
实体是新的,尚未收到数据库生成的密钥
价值观在这种情况下,请使用“添加”方法或“添加”实体状态
跟踪图形,然后将非新实体的状态设置为
“未更改”或“修改”,视情况而定
如果我回滚并使用UnityConfig中的基本行
container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
container.RegisterType<ILogger, ElmahLogger>();
container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
container.RegisterType<IOrderRequestRepositoryFactory, OrderRequestRepositoryFactory>();
container.RegisterType();
。。。一切正常。我相信这两行都使用相同的默认生存期管理器TransientLifetimeManager,所以奇怪的是,使用InjectionConstructor似乎仍然会破坏一些东西。这里的问题是,您的
OrderRequestRepository
正在处理它不拥有的东西。intranetapplicationcontext
被注入到存储库中,由于OrderRequestRepository
不知道该依赖项的生活方式是什么,因此它无法处理它
您可能注册了intranetapplicationcontext
,以便在存储库处于暂时状态时拥有每个请求的生活方式
解决方案:只有当您有任何东西需要自行处理时,才实现IDisposable。在您的情况下,这意味着您的存储库根本不需要IDisposable。我已经解决了这个问题,而不是修复错误: 我使用InjectionConstructor以便可以传递多个参数,但作为替代方法,我对其进行了更改,以便将单个参数,即工厂对象传递给存储库
public class OrderRequestRepository : IOrderRequestRepository
{
private readonly IntranetApplicationsContext _context;
private readonly ILogger _logger;
public OrderRequestRepository(IOrderRequestRepositoryFactory respositoryFactory)
{
_context = respositoryFactory.CreateIntranetApplicationsContext();
_logger = respositoryFactory.CreateLogger();
}
...
}
工厂
public interface IOrderRequestRepositoryFactory
{
ILogger CreateLogger();
IntranetApplicationsContext CreateIntranetApplicationsContext();
}
public class OrderRequestRepositoryFactory : IOrderRequestRepositoryFactory
{
public ILogger CreateLogger()
{
return new ElmahLogger();
}
public IntranetApplicationsContext CreateIntranetApplicationsContext()
{
return new IntranetApplicationsContext();
}
}
单位配置
container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
container.RegisterType<ILogger, ElmahLogger>();
container.RegisterType<IOrderRequestRepository, OrderRequestRepository>();
container.RegisterType<IOrderRequestRepositoryFactory, OrderRequestRepositoryFactory>();
container.RegisterType();
container.RegisterType();
container.RegisterType();
这是因为我没有使用InjectionConstructor,所以不需要获取相关的错误,并且仍然可以通过使用我的工厂传递任意多的参数