无法解决与 Unity 和 WebAPI 的依赖关系
Failing to resolve dependencies with Unity and WebAPI
我在 WebAPI 中尝试 运行 我的控制器操作时收到这个奇怪的错误:
An error occurred when trying to create a controller of type 'PostController'. Make sure that the controller has a parameterless public constructor.
Resolution of the dependency failed, type = "Example.Controllers.PostController", name = "(none)".
异常发生在:调用构造函数 Example.Models.PostRepository() 时。
异常是:NullReferenceException - 未将对象引用设置为对象的实例。
这是有问题的代码:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType<IPostRepository, PostRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ExampleApi",
routeTemplate: "api/{controller}"
);
}
}
public class PostController : ApiController
{
IPostRepository _repository;
public PostController(IPostRepository repository)
{
_repository = repository;
}
public IEnumerable<Post> GetAllProducts()
{
return _repository.GetAll();
}
}
public class PostRepository : IPostRepository
{
private IDbConnection _connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
public IEnumerable<Post> GetAll()
{
return _connection.Query<Post>("SELECT * FROM Posts").ToList();
}
}
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer Container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.Container = container;
}
public object GetService(Type serviceType)
{
if (!Container.IsRegistered(serviceType))
{
if (serviceType.IsAbstract || serviceType.IsInterface)
{
return null;
}
}
return Container.Resolve(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return Container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = Container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
Container.Dispose();
}
}
有人知道可能是什么原因吗?我遵循了本教程:http://www.asp.net/web-api/overview/advanced/dependency-injection
以下 link 有一个基于您提到的同一教程的工作项目。
除了数据库将以 localdb 为目标外,与您的代码没有太大区别,并且在 UnityResolver 上没有对 Abstract class 的检查,我认为这没有任何区别。
现在,您可以使用该项目作为启动点来添加您的逻辑,并确切知道失败的时间和原因。
希望这对您有所帮助。
根据我的经验,当我看到此消息时,通常是无法构建某些依赖项或缺少依赖项。您已将 IPostRepository 注册到 PostRepository,这样看起来不错。 PostRepository 中创建的 SqlConnection 呢?您能否 运行 一些仅针对存储库的测试代码,看看它是否可以自行构建?
此外,在浏览您的代码时,还会检查是否存在阻止您在 UnityResolver 中解析 IPostRepository 的接口 class?
if (serviceType.IsAbstract || serviceType.IsInterface)
{
return null;
}
我在 WebAPI 中尝试 运行 我的控制器操作时收到这个奇怪的错误:
An error occurred when trying to create a controller of type 'PostController'. Make sure that the controller has a parameterless public constructor.
Resolution of the dependency failed, type = "Example.Controllers.PostController", name = "(none)".
异常发生在:调用构造函数 Example.Models.PostRepository() 时。 异常是:NullReferenceException - 未将对象引用设置为对象的实例。
这是有问题的代码:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
container.RegisterType<IPostRepository, PostRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ExampleApi",
routeTemplate: "api/{controller}"
);
}
}
public class PostController : ApiController
{
IPostRepository _repository;
public PostController(IPostRepository repository)
{
_repository = repository;
}
public IEnumerable<Post> GetAllProducts()
{
return _repository.GetAll();
}
}
public class PostRepository : IPostRepository
{
private IDbConnection _connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
public IEnumerable<Post> GetAll()
{
return _connection.Query<Post>("SELECT * FROM Posts").ToList();
}
}
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer Container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.Container = container;
}
public object GetService(Type serviceType)
{
if (!Container.IsRegistered(serviceType))
{
if (serviceType.IsAbstract || serviceType.IsInterface)
{
return null;
}
}
return Container.Resolve(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return Container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = Container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
Container.Dispose();
}
}
有人知道可能是什么原因吗?我遵循了本教程:http://www.asp.net/web-api/overview/advanced/dependency-injection
以下 link 有一个基于您提到的同一教程的工作项目。
除了数据库将以 localdb 为目标外,与您的代码没有太大区别,并且在 UnityResolver 上没有对 Abstract class 的检查,我认为这没有任何区别。
现在,您可以使用该项目作为启动点来添加您的逻辑,并确切知道失败的时间和原因。
希望这对您有所帮助。
根据我的经验,当我看到此消息时,通常是无法构建某些依赖项或缺少依赖项。您已将 IPostRepository 注册到 PostRepository,这样看起来不错。 PostRepository 中创建的 SqlConnection 呢?您能否 运行 一些仅针对存储库的测试代码,看看它是否可以自行构建?
此外,在浏览您的代码时,还会检查是否存在阻止您在 UnityResolver 中解析 IPostRepository 的接口 class?
if (serviceType.IsAbstract || serviceType.IsInterface)
{
return null;
}