Pomyłka Ninject UnitOfWork
Używam Ninject cały czas z moimi aplikacjami MVC 3, ale próbuję zmienić wzorzec dla moich obiektów danych tak, aby korzystał z UnitOfWork i mam problem z ustaleniem, jak uzyskać Ninject, aby właściwie to obsługiwał.
Wiem, że moja implementacja klas działa, gdy są skonstruowane ręcznie w taki sposób w mojej aplikacji konsoli:
<code>IDatabaseFactory factory = new DatabaseFactory(); IUnitOfWork worker = new UnitOfWork(factory); IBlogCategoryDao dao = new BlogCategoryDao(factory); IBlogCategoryService service = new BlogCategoryService(dao); BlogCategory category = service.GetById(id); try { if (category != null) { service.Delete(category); worker.Commit(); Console.WriteLine("Category deleted successfully!"); } else { Console.WriteLine("Entity doesn't exist."); } } catch (Exception ex) { Console.WriteLine("Error deleting category: {0}", ex.Message); } </code>
W mojej aplikacji MVC 3 używam pakietu Ninject.MVC3 NuGet, a jest to metoda RegisterServices.
<code>private static void RegisterServices(IKernel kernel) { kernel.Bind<IDatabaseFactory>().To<DatabaseFactory>(); kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope(); kernel.Bind<IBlogCategoryDao>().To<BlogCategoryDao>(); kernel.Bind<IBlogDao>().To<BlogDao>(); kernel.Bind<IBlogCategoryService>().To<BlogCategoryService>(); kernel.Bind<IBlogService>().To<BlogService>(); } </code>
Chociaż działa to w większości, pobieranie żądań, wszystkie żądania POST (Insert, Update, Delete) nie są wykonywane. Nie ma wyjątku, a gdy go przejdę, przechodzi on bez problemu przez metodę SaveChanges () i zwraca z powrotem stos, ale nic nie jest wykonywane. Wiem więc, że czegoś brakuje w mojej konfiguracji Ninject.
Oto moja klasa jednostki pracy.
<code>public class UnitOfWork : IUnitOfWork { private Database _database; <-- DbContext derived class private readonly IDatabaseFactory _databaseFactory; public UnitOfWork(IDatabaseFactory databaseFactory) { this._databaseFactory = databaseFactory; } public Database Database { get { return _database ?? (_database = _databaseFactory.Get()); } } public void Commit() { Database.Commit(); } } </code>
Oto klasa DatabaseFactory:
<code>public class DatabaseFactory : Disposable, IDatabaseFactory { private Database _database; public DatabaseFactory() { } public virtual Database Get() { if (_database == null) { _database = DataObjectFactory.CreateContext(); } return _database; } protected override void DisposeCore() { if (_database != null) { _database.Dispose(); } } } </code>
I moja klasa DataObjectFactory:
<code>public static class DataObjectFactory { private static readonly string _connectionString; /// <summary> /// Static constructor. Reads the connectionstring from web.config just once. /// </summary> static DataObjectFactory() { string connectionStringName = ConfigurationManager.AppSettings.Get("ConnectionStringName"); _connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; } /// <summary> /// Creates the Context using the current connectionstring. /// </summary> /// <remarks> /// Gof pattern: Factory method. /// </remarks> /// <returns>Action Entities context.</returns> public static Database CreateContext() { return new Database(_connectionString); } } </code>
Jest to podobny wzór jak w aplikacji EFMVC CodePlex, ale nie używam AutoFac.
Wszelkie przemyślenia na ten temat są doceniane.
Dzięki.