Ninject的UnitOfWork混乱(Ninject UnitOfWork confusion)

2019-07-29 07:36发布

我用Ninject所有的时间与我的MVC 3应用程序,但我试图改变模式为我的数据对象使用的UnitOfWork,我有麻烦找出如何让Ninject妥善处理这个问题。

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

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

在我的MVC 3应用程序我使用的是Ninject.MVC3 NuGet包,并且这是在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。

任何对此的思考是赞赏。

谢谢。

Answer 1:

我只是这样做:

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代码连接字符串。



文章来源: Ninject UnitOfWork confusion