我很难搞清楚这一点。我已经将Repository和Unit of Work模式实现为我的数据库的数据访问抽象。我正在使用依赖注入将它们注入控制器。问题是当控制器被丢弃时,它会处理存储库,但是当我刷新页面时,存储库中的DbContext对象为空(我认为不应该这样)。类的实现如下所示。
这是数据库存储库类:
public class ConferenceCrawlyDbRepository : IConferenceCrawlyDbRepository
{
private ConferenceCrawlyDbContext _context = null;
private static ConferenceCrawlyDbRepository _instance = null;
public IRepository<AcademicDegree> AcademicDegrees { get; private set; }
public IRepository<Conference> Conferences { get; private set; }
public IRepository<ConferenceComment> ConferenceComments { get; private set; }
public IRepository<ConferenceRating> ConferenceRatings { get; private set; }
public IRepository<ConnectionConferenceRecommendation> ConnectionConferenceRecommendation { get; private set; }
public IRepository<Country> Countries { get; private set; }
public IRepository<ImportantDate> ImportantDates { get; private set; }
public IRepository<Topic> Topics { get; private set; }
public IRepository<UserProfile> UserProfiles { get; private set; }
public IRepository<UserProfileSettings> UserProfileSettings { get; private set; }
public IRepository<UsersConnection> UserConnections { get; private set; }
public IRepository<Venue> Venues { get; private set; }
private ConferenceCrawlyDbRepository(ConferenceCrawlyDbContext context)
{
_context = context;
AcademicDegrees = new Repository<AcademicDegree>(context);
Conferences = new Repository<Conference>(context);
ConferenceComments = new Repository<ConferenceComment>(context);
ConferenceRatings = new Repository<ConferenceRating>(context);
ConnectionConferenceRecommendation = new Repository<ConnectionConferenceRecommendation>(context);
Countries = new Repository<Country>(context);
ImportantDates = new Repository<ImportantDate>(context);
Topics = new Repository<Topic>(context);
UserProfiles = new Repository<UserProfile>(context);
UserProfileSettings = new Repository<UserProfileSettings>(context);
UserConnections = new Repository<UsersConnection>(context);
Venues = new Repository<Venue>(context);
}
public static ConferenceCrawlyDbRepository Instance
{
get
{
if (_instance == null)
_instance = new ConferenceCrawlyDbRepository(new ConferenceCrawlyDbContext());
return _instance;
}
}
public bool CommitChanges()
{
try
{
return _context.SaveChanges() > 0;
}
catch
{
// TODO: Add logging
return false;
}
}
public void Dispose()
{
if (_context != null)
_context.Dispose();
}
这是通用存储库类:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private ConferenceCrawlyDbContext _context = null;
private DbSet<TEntity> _dbSet = null;
public Repository(ConferenceCrawlyDbContext context)
{
_context = context;
_dbSet = context.Set<TEntity>();
}
public DbSet<TEntity> DbSet
{
get
{
return _dbSet;
}
}
public bool Add(TEntity entity)
{
try
{
DbSet.Add(entity);
return true;
}
catch (Exception ex)
{
// TODO: Add logging
return false;
}
}
public bool Update(TEntity entity)
{
try
{
var entry = _context.Entry<TEntity>(entity);
DbSet.Attach(entity);
entry.State = EntityState.Modified;
return true;
}
catch(Exception ex)
{
// TODO: Add logging
return false;
}
}
public bool Remove(TEntity entity)
{
try
{
DbSet.Remove(entity);
return true;
}
catch (Exception ex)
{
// TODO: Add logging
return false;
}
}
public IQueryable<TEntity> GetAll()
{
return DbSet;
}
public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.Where(predicate);
}
public TEntity FindById(params object[] keys)
{
return DbSet.Find(keys);
}
public bool Contains(Expression<Func<TEntity, bool>> predicate)
{
return _dbSet.Any(predicate);
}
public bool CommitChanges()
{
try
{
return _context.SaveChanges() > 0;
}
catch
{
// TODO: Add logging
return false;
}
}
public void Dispose()
{
if (_context != null)
_context.Dispose();
}
}
这是依赖注入的自定义控制器工厂:
public class CustomControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
{
if (controllerType.GetConstructor(new Type[] { typeof(IConferenceCrawlyDbRepository) }) != null)
return Activator.CreateInstance(controllerType, new object[] { ConferenceCrawlyDbRepository.Instance }) as Controller;
else if (controllerType.GetConstructor(new Type[] { typeof(IConferenceCrawlyDbRepository), typeof(IMailService) }) != null)
return Activator.CreateInstance(controllerType, new object[] { ConferenceCrawlyDbRepository.Instance,
#if DEBUG
MockMailService.Instance
#else
MailService.Instance
#endif
}) as Controller;
}
return base.GetControllerInstance(requestContext, controllerType);
}
最后,控制器及其动作:
public class HomeController : Controller
{
private IConferenceCrawlyDbRepository _dbRepository;
private IMailService _mailService;
public HomeController(IConferenceCrawlyDbRepository dbRepository, IMailService mailService)
{
_dbRepository = dbRepository;
_mailService = mailService;
}
//
// GET: /
public ActionResult Index()
{
var countries = _dbRepository.Countries.GetAll().ToList();
return View(countries);
}
//
// GET: /Home/About
public ActionResult About()
{
return View();
}
//
// GET: /Home/Contact
public ActionResult Contact()
{
return View(new Contact());
}
//
// POST: /Home/Contact
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Contact(Contact contact)
{
if (ModelState.IsValid)
{
if (await _mailService.SendMail(contact.Email, contact.Title,
String.Format("{1}{0}{2}", Environment.NewLine, contact.Message, String.IsNullOrEmpty(contact.Name) ? "Anonimous" : contact.Name)))
{
ViewBag.SuccessMessage = "Comment has been successfully sent.";
return View(new Contact());
}
else
ViewBag.ErrorMessage = "Couldn't send your email. Please try again later";
}
return View(contact);
}
protected override void Dispose(bool disposing)
{
if (_dbRepository != null)
_dbRepository.Dispose();
base.Dispose(disposing);
}
}
当我调用存储库时,异常会在索引操作中抛出,但只有在第一次访问此控制器之后,它才会在存储库中显示DbContext对象。我显然做错了什么,但我无法理解。
答案 0 :(得分:0)
经过长时间的盯着和调试代码,我弄明白了。这很简单,因为我在ConferenceCrawlyDbRepository中处理上下文我还应该设置_instance对象,它使用它来为null,然后它将与DbContext对象一起重新创建。我现在摔得太傻了......