2012-05-09 25 views
0

我一直在使用Ninject与我的MVC 3应用程序,但我试图改变我的数据对象的模式以使用UnitOfWork,并且我无法弄清楚如何让Ninject正确处理这个问题。Ninject UnitOfWork混淆

我知道他们什么时候手工构建这样在我的控制台应用程序我的实现类的工作:

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); 
} 

在我使用的是Ninject.MVC3 NuGet包我的MVC 3应用程序,这是RegisterServices方法。

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>(); 
} 

虽然这在大多数情况下都可以使用Get请求,但所有POST请求(插入,更新,删除)都不会执行。没有异常抛出,并且当我逐步完成它时,它会顺利通过SaveChanges()方法并返回堆栈,但不执行任何操作。所以我知道我必须用我的Ninject配置丢失一些东西。

这是我的工作单元班。

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(); 
    } 
} 

这里的DatabaseFactory类:

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(); 
     } 
    } 
} 

而且我DataObjectFactory类:

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); 
    } 
} 

这是因为在EFMVC CodePlex上的应用程序采用了类似的模式,但我不使用AutoFac。

对此的任何想法表示赞赏。

谢谢。

+0

什么是数据库?这似乎过于复杂。 –

+0

数据库是DbContext的派生类。它包含IDbSet 属性。 – Kahanu

+0

我实际上是通过重构它来工作的。我完全删除了DatabaseFactory类,而是使用UnitOfWork实例注入了具体的Repository类(BlogCategoryDao)。 BlogCategoryDao(IUnitOfWork)。这工作更好,更干净,而且它确实有效! – Kahanu

回答

4

我只是这样做:

kernel.Bind<IUnitOfWork>.To<EFUnitOfWork>().InRequestScope(); 

EFUnitOfWork.cs

public class EFUnitOfWork : DbContext, IUnitOfWork 
{ 
    // your normal DbContext plus your IUnitOfWork members that delegate to EF context 
} 

由于EF已经实现了单位工作的一种形式,这可以让你用一个更通用的接口,它和轻松注入。

另外,您可以为连接字符串实现EF构造函数,并将它们传递给基础构造函数。然后,您可以使用Ninject .WithConstructorArgument()使用您的AppSettings代码配置连接字符串。

+0

我看不到.InRequestContext()扩展名。你的意思是.InRequestScope()?我已经启用了它,但它仍然不起作用。 – Kahanu

+0

@Kahanu - 对不起,误解了它。 –

+1

我正面临一个非常类似的问题,我刚刚做的是将InRequestScope添加到ninject内核的DbFactory绑定中。 –