实体框架-依赖注入(Ninject)和Moq问题



我使用的是标准ASP。Net MVC4 web应用程序,同时学习教程。我已经遵循了第一部分中的所有步骤,在使用Moq mocking框架时,所有步骤都很好。

在第一部分中,它导致用于登录和注册的标准.net应用程序的链接被删除,但功能仍然存在,所以我重新添加了它们,因为我知道问题出在连接字符串上。

最初是用con字符串。但我解决了这个问题。然而,当我更改代码以引用具有工作con字符串的本地DB时,我仍然会得到一个Null Ref异常。在这一点上,我已经浏览了好几次代码,但没有发现哪里出了问题。所以我粘贴下面的示例代码作为参考,希望有人能帮助我。

这是一个示例高尔夫商店应用程序,它只有一张桌子。项目。该项目的结构是一个标准的MVC4 web应用程序,还有一个额外的Domain项目,其中包含抽象、具体和实体的文件夹,因为它使用实体框架的方式我不确定。

只是澄清一下,当我注释Infrastructure \NinjectControllerFactory.cs中的最后一行并取消注释moq代码时。一切正常。只有当我注释掉代码并取消注释最后一行时,我才会得到错误。即使表中有3条记录。

以下是域项目中的代码域\实体\项目.cs

public class Item
{
    public int ItemId { get; set; }
    public string ItemName { get; set; }
    public string ItemDesc { get; set; }
    public string Brand { get; set; }
    public string Category { get; set; }
    public decimal ItemPrice { get; set; }
}

域\摘要\ItemRepository.cs

public interface IItemRepository
{
    IQueryable<Item> Items { get; }
}

域\混凝土\ EFItemRepository.cs

public class EFItemRepository : IItemRepository
{
    private EFdbContext context = new EFdbContext();
    public IQueryable<Item> Items
    {
        get { return context.Items; }
    }
}

域\混凝土\EFdbContext.cs

class EFdbContext
{
    public DbSet<Item> Items { get; set; }
}

我可能错了这个假设,但我不知道上面的代码是在哪里使用的,也不知道如何实际修改我的代码来使用它。无论如何,下面是MVC4 Web项目。在它中,我有一个基础设施文件夹,其中有一个类如下:

高尔夫商店。WebUI\基础设施\NinjectControllerFactory.cs

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernel;
    public NinjectControllerFactory()
    {
        ninjectKernel = new StandardKernel();
        AddBinding();
    }
    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        //return base.GetControllerInstance(requestContext, controllerType);
        return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);
    }
    private void AddBinding()
    {
        ////Old binding to bind to moq item repo - All this works
        //Mock<IItemRepository> mock = new Mock<IItemRepository>();
        //mock.Setup(m => m.Items).Returns(new List<Item>
        //{
        //    new Item{ItemId=1,ItemName="Trolley", ItemPrice=100M},
        //    new Item{ItemId=1,ItemName="Irons", ItemPrice=255M},
        //    new Item{ItemId=1,ItemName="Driver", ItemPrice=129.67M}
        //}.AsQueryable());
        //ninjectKernel.Bind<IItemRepository>().ToConstant(mock.Object);

        //New binding to bind to real db
        ninjectKernel.Bind<IItemRepository>().To<EFItemRepository>();
    }
}

上面的代码大部分是注释,因为大部分都被Moq mocking框架使用。在我看来,最后一行(我可能错了)似乎是该方法中唯一需要的连接到实时数据库的行,但它似乎没有任何作用。

下面是项目管理员:

public class ItemController : Controller
{
    private IItemRepository repository;
    public ItemController(IItemRepository itemRepository)
    {
        this.repository = itemRepository;
    }
    public ViewResult Index()
    {
        return View(repository.Items);
    }
}

以下是项目视图:

@model IEnumerable<SHGolfStore.Domain.Entities.Item>
@{
    ViewBag.Title = "Index";
}
@{
    //TODO FR: Part 6
}
<h2>MY DI Stuff Part 1</h2>
<br />
@foreach (var i in Model)
{
    <div class="item">
        <h4>@i.ItemName (€@i.ItemPrice)</h4>
    </div>
}

最后,我在Application_Start()方法下将此行添加到MvcApplication类中的Global.asax.cs文件中:

        ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

下面是我尝试使用的2个连接字符串。DefaultConnection可以工作,让我注册和登录没有问题。但是,当我将另一个添加到EFDbContext或按照教程中的建议将其重命名时,即使其他内容都没有更改,我也会开始出现错误。然而,即使未修改DefaultConnection,我仍然会得到下面关于视图中null ref的错误解释。这正是我想要解决的问题。

<add name="EFDbContext" connectionString="Data Source=(LocalDb)v11.0;Initial Catalog=aspnet-SHGolfStore.WebUI-20140413135241;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnet-SHGolfStore.WebUI-20140413135241.mdf" providerName="System.Data.SqlClient" />
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)v11.0;Initial Catalog=aspnet-SHGolfStore.WebUI-20140413135241;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnet-SHGolfStore.WebUI-20140413135241.mdf" providerName="System.Data.SqlClient" />

我看不到明显的模型。此外,虽然我确实按照解释将EF添加到了项目中,但由于没有生成EDMX文件或数据集,我看不出它在哪里被使用。如果它是生成的,我不明白它是如何使用的。所以我想澄清一下。

只是重申一下,当我注释Infrastructure \NinjectControllerFactory.cs中的最后一行并取消注释moq代码时。一切正常。只有当我注释掉代码并取消注释最后一行时,我才会得到错误。即使表中有3条记录。

我在foreach部分的View上得到了一个null引用异常。我能理解为什么数据库没有被访问,但我还不足以修复它。

再次感谢您的帮助。

因为我使用StackOverflow作为自己的参考,我最终解决了这个问题。我想把它记录在这里,供我自己参考,并说明其他人可能有同样的问题。

本质上,这是连接字符串的问题。

我不明白的是,一个项目中通常有2个连接字符串。

第一个连接字符串(通常称为DefaultConnection)是用于访问DB的实际连接字符串,主要由登录/注册系统使用,EF使用第二个。

第二个连接字符串是实体框架使用的连接字符串。如果你像我一样把你的项目分开,我在另一个远离web应用程序的项目中有我的EF类。正确的EF con字符串存储在那里的App.Config中。当我把它从那里拿出来,用我从那里得到的替换web.config中的旧版本时,它几乎奏效了。

我不得不做一些其他的基本重组,使我的代码引用新的con字符串,但本质上这就是所需要的。

如果其他人对我如何重组或改进有任何建议,或者想要更多信息,请随时添加评论或答案,我会回来编辑。

最新更新