当我点击试图访问数据库的代码时,我得到一个空引用异常。
这是在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工作?
答案 0 :(得分: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;
}
}
答案 1 :(得分:2)
告诉容器如何使用以下配置解析IAppUserRepository
。
container.RegisterAutoWiredAs<AppUserRepository, IAppUserRepository>();
RegisterAutoWiredAs
会注入IDbConnectionFactory
依赖项
答案 2 :(得分:0)
您没有展示您的决心IAppUserRepository
,但是使用Funq,您必须在注册抽象时在工厂委托实例中执行任何项目注入。
有关详细信息,请参阅http://funq.codeplex.com/discussions/217686。
答案 3 :(得分: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;}
}