2013-04-05 63 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;} 
} 
相關問題