将单片ASP.NET MVC应用程序拆分为N层应用程序时遇到了很大困难。在以下示例中,在第一次调用 _messageRepo.Create()期间,抛出一个异常,指出 DbContext 无法使用,因为它已经被处理掉了。
我看不出这是怎么回事,试图打破 Dispose()方法实际上并没有导致应用程序在调试过程中中断。
基本结构如下:
在需要时重建这些实例,如以下示例所示
using(var context = new MyContext())
{
_messageRepo = new MessageRepository(context);
_idRepo = new IdentityRepository(context);
var status = _messageRepo.GetStatus(Int32.Parse(message.To));
message.To = status.Header.From.Name;
message.ToHash = Obfuscate.SaltAndHash(message.To);
message.Subject = "RE:" + status.Header.Subject;
var toUser = _idRepo.Get(message.To);
var fromUser = _idRepo.Get(_userName);
var rawMessage = new Message()
{
Content = message.Content,
Attachments = GetAttachments(message.AttachmentIds)
};
var header = new MessageHeader()
{
To = toUser,
From = fromUser,
Subject = message.Subject
};
_messageRepo.Create(new MessageStatus()
{
CreatedAt = DateTime.Now,
IsRead = false,
IsSpam = false,
IsTrash = false,
Message = rawMessage,
Header = header,
Owner = header.To
});
_messageRepo.Create(new MessageStatus()
{
CreatedAt = DateTime.Now,
IsRead = false,
IsSpam = false,
IsTrash = false,
Message = rawMessage,
Header = header,
Owner = header.From
});
context.Commit();
Email.SendNewMessageNotification(fromUser.Email, toUser.Email);
}
存储库方法是LINQ单行程序,它使用代码第一种方法通过Entity Framework从数据库中检索模型。
这种方法有问题吗?我最初确实有MyContext实现了IUnitOfWork,但我删除了它,直到我得到这个不太复杂的方法功能。
此外,我正在使用IoC框架(AutoFac)来加载这些接口实现的实例。如果这是问题所在,那么我需要对我的逻辑进行哪些更改以适应AutoFac?
//in Global.asax.cs
builder.RegisterType<PonosContext>().As<PonosContext>().InstancePerHttpRequest();
//Example repo constructor
public MessageRepository(PonosContext context)
{
_db = context;
}
答案 0 :(得分:2)
当您使用IoC容器时,您永远不应该调用容器管理的新服务。在此示例中,您不应使用:
using(var context = new MyContext())
_messageRepo = new MessageRepository(context);
_idRepo = new IdentityRepository(context);
应该注入您的依赖项(例如构造函数)。
如何使用AutoFac注册您的存储库?也许你的存储库configurard是单身?当存储库被重用于第二个http请求时,这可能导致dispose异常。
答案 1 :(得分:0)
DataContexts不应该活得太久:)应该创建它们并将它们放置在接近它们的用途。
考虑不要在不同的存储库之间传递相同的实例。如果要在单个事务中包装多个操作,请查看TransactionScope