4

在访问尝试访问数据库的代码时,出现空引用异常。

这是在 global.asax 中,我已经通过调试器逐步执行此代码。

public class MvcApplication : System.Web.HttpApplication
{
    public class DmsAppHost : AppHostBase
    {
        public DmsAppHost() : base("API", typeof(AppUsersService).Assembly) { }

        public override void Configure(Funq.Container container)
        {
            var dbConnectionFactory = new OrmLiteConnectionFactory("Server=localhost;Port=5432;User Id=dms; Password=dms; Database=dms", PostgreSqlDialect.Provider);
            container.Register<IDbConnectionFactory>(dbConnectionFactory);
            container.RegisterAutoWiredAs<AppUserRepository, IAppUserRepository>();
        }
    }

    protected void Application_Start()
    {
        new DmsAppHost().Init();

        AreaRegistration.RegisterAllAreas();

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BootstrapSupport.BootstrapBundleConfig.RegisterBundles(System.Web.Optimization.BundleTable.Bundles);
    }

}

当我点击这段代码时(使用 (var db = DbConnectionFactory.OpenDbConnection())),我得到了 NullReferenceException。

你调用的对象是空的。

public class AppUserRepository : IAppUserRepository
{
    public IDbConnectionFactory DbConnectionFactory { get; set; }

    public AppUser GetAppUserByUsername(string username)
    {
        AppUser appUser;
        using (var db = DbConnectionFactory.OpenDbConnection())
        {
            appUser = db.QuerySingle<AppUser>(new { username });
        }
        return appUser;
    }
}

我是假设我的 Connection 有问题,还是我没有做正确的事情来使 Funq 工作?

4

4 回答 4

9

您已经展示了一些将依赖项注入您的AppUserRepository类的 Funq 容器配置。但是你还没有展示这个类是如何以及在哪里使用的。由于您的问题被标记为asp.net-mvc我假设这发生在 ASP.NET MVC 控制器操作中。类似于以下内容:

public class HomeController: Controller
{
    private readonly IAppUserRepository repo;
    public HomeController(IAppUserRepository repo)
    {
        this.repo = repo;
    }

    public ActionResult Index(int id)
    {
        var model = this.repo.Get(id);
        return View(model);
    }
}

如果你想在 ASP.NET MVC 中使用依赖注入框架,你将不得不编写一个自定义dependency resolver注入到控制器中。

所以让我们继续为 Funq 写一个:

public class FunqDependencyResolver : IDependencyResolver
{
    private readonly ContainerResolveCache cache;
    public FunqDependencyResolver(Container container)
    {
        this.cache = new ContainerResolveCache(container);
        var controllerTypes =
            (from type in Assembly.GetCallingAssembly().GetTypes()
             where typeof(IController).IsAssignableFrom(type)
             select type).ToList();
        container.RegisterAutoWiredTypes(controllerTypes);
    }

    public object GetService(Type serviceType)
    {
        return this.cache.CreateInstance(serviceType, true);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return Enumerable.Empty<object>();
    }
}

然后我们可以注册它Application_Start

protected void Application_Start()
{
    var container = new Container();
    var dbConnectionFactory = new OrmLiteConnectionFactory("Server=localhost;Port=5432;User Id=dms; Password=dms; Database=dms", PostgreSqlDialect.Provider);
    container.Register<IDbConnectionFactory>(dbConnectionFactory);
    container.RegisterAutoWiredAs<AppUserRepository, IAppUserRepository>();
    DependencyResolver.SetResolver(new FunqDependencyResolver(container));

    AreaRegistration.RegisterAllAreas();

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BootstrapSupport.BootstrapBundleConfig.RegisterBundles(System.Web.Optimization.BundleTable.Bundles);
}

另外,我建议您为您的AppUserRepository类使用构造函数注入,因为这DbConnectionFactory是该类正常工作的绝对必需的依赖项:

public class AppUserRepository : IAppUserRepository
{
    private readonly IDbConnectionFactory dbConnectionFactory;
    public class AppUserRepository(IDbConnectionFactory dbConnectionFactory)
    {
        this.dbConnectionFactory = dbConnectionFactory;
    }

    public AppUser GetAppUserByUsername(string username)
    {
        AppUser appUser;
        using (var db = this.dbConnectionFactory.OpenDbConnection())
        {
            appUser = db.QuerySingle<AppUser>(new { username });
        }
        return appUser;
    }
}
于 2013-04-15T08:31:11.917 回答
2

告诉容器如何IAppUserRepository使用以下配置进行解析。

container.RegisterAutoWiredAs<AppUserRepository, IAppUserRepository>();

RegisterAutoWiredAs将注入IDbConnectionFactory依赖

于 2013-04-05T19:35:04.913 回答
0

您没有展示您的 resolve 方式IAppUserRepository,但使用 Funq,您必须在注册抽象时在您的工厂委托实例中进行任何项目注入。

有关详细信息,请参阅http://funq.codeplex.com/discussions/217686

于 2013-04-05T19:29:15.583 回答
0

你的问题是它DbConnectionFactory不会成为一个对象,所以它仍然是空的

就像你会这样做

public TextBlock nullBlock; // it's your public IDbConnectionFactory DbConnectionFactory { get; set; }
nullBlock.Text;             //           DbConnectionFactory.OpenDbConnection()

你需要设置一个对象

在你的情况下,像

var obj = new AppUserRepository();
obj.DbConnectionFactory = .... //

如果您将其填写在一些隐藏代码中,则附加

你应该这样做并设置一个断点,也许你的过度处理的对象是空的

private IDbConnectionFactory _dbConnectionFactory
public IDbConnectionFactory DbConnectionFactory 
{
      get {return _dbConnectionFactory; }
      set {_dbConnectionFactory=value;}
}
于 2013-04-15T07:29:57.523 回答