依赖注入(Ninject)和Moq问题

时间:2014-04-13 16:19:08

标签: entity-framework asp.net-mvc-4 dependency-injection ninject moq

我正在使用标准的ASP.Net MVC4 Web应用程序来完成教程。我已经按照第一部分中的所有步骤进行操作,当使用Moq模拟框架时,一切运行良好。

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

最初是con字符串。但我解决了这个问题。但是,当我更改代码以引用具有工作con字符串的本地DB时,我仍然得到Null Ref异常。此时我已经多次浏览过代码并且没有看到错误。所以我粘贴下面的示例代码以供参考,希望有人可以帮助我。

它是一个样本高尔夫商店应用程序,它只有一个表。项目。该项目的结构是一个标准的MVC4 Web应用程序,其中包含一个Domain的附加项目,其中包含Abstract,Concrete和Entities的文件夹,因为它可能以我不确定的方式使用实体框架。

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

以下是域项目中的代码 域\实体\ Item.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; }
}

域\摘要\ IItemRepository.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项目。在其中我有一个基础架构的文件夹,其中一个类如下:

GolfStore.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模拟框架使用的。在我看来,最后一行(我可能错了)是这个方法中唯一需要连接到实时数据库的行,但似乎没有做任何事情。

以下是项目控制器:

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上得到一个空引用异常。我可以理解为什么如果没有访问数据库但我不能理解它。

再次感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

当我使用StackOverflow作为我自己的参考时,我终于解决了这个问题。我想在此处记录它以供我自己参考,并且包装其他人可能会遇到同样的问题。

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

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

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

第二个连接字符串是实体框架使用的字符串。如果您像我一样将项目分开,那么我的EF课程将在远离Web应用程序的另一个项目中完成。正确的EF con字符串存储在那里的App.Config中。当我把它从那里拉出来,并将web.config中的旧版本替换为我从那里获得的版本时,它几乎可以工作。

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

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