2013-04-05 36 views
3

当我试图访问数据库的代码时,我得到一个空引用异常。为什么我的Funq容器无法正常工作?

这是在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; 
    } 
} 

我该承担的东西是错误与我的连接或者是有什么我不这样做的权利,使Funq工作?

+0

我也试过这与SqlLite并得到同样的问题。看起来Funq并没有创建我的DbConnectionFactory实例。 – 2013-04-05 19:29:52

+0

在这里你调用'DbConnectionFactory.OpenDbConnection()'我看不到你在哪里实际上'创建连接'我在这里忽略了一些东西 – MethodMan 2013-04-05 19:30:34

+0

它应该由Funq(IOC容器)在global.asax上面的文件。至少这是我理解它的工作原理。 – 2013-04-05 19:53:29

回答

9

你已经显示了一些Funq容器配置,它将注入依赖关系到AppUserRepository类中。但是你没有展示这个班如何以及在哪里使用。由于你的问题被标记为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; 
    } 
} 
2

告诉容器如何使用以下配置来解析IAppUserRepository

container.RegisterAutoWiredAs<AppUserRepository, IAppUserRepository>();

RegisterAutoWiredAs将注入IDbConnectionFactory依赖

+0

我补充说,但是当它到达AppUserRepository.GetAppUserByUsername(“user”)的代码时,我也会得到一个空引用异常。 – 2013-04-05 19:40:29

+0

您的服务是否依赖于接口或具体类型? – jeffgabhart 2013-04-05 19:43:00

+0

我在服务中公开了这个IAppUserRepository AppUserRepository {get;组; } – 2013-04-05 19:46:37

0

您的问题是,所以还是空

这就像你会做这个

public TextBlock nullBlock; // it's your public IDbConnectionFactory DbConnectionFactory { get; set; } 
nullBlock.Text;    //   DbConnectionFactory.OpenDbConnection() 
DbConnectionFactory不会成为一个对象

你需要设置一个对象

你的情况类似

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

另外,如果你填写在一些隐藏的代码

你应该这样做,并设置一个断点也许你overhanded对象为空

private IDbConnectionFactory _dbConnectionFactory 
public IDbConnectionFactory DbConnectionFactory 
{ 
     get {return _dbConnectionFactory; } 
     set {_dbConnectionFactory=value;} 
} 
相关问题