无法使用Unity和WebAPI解决依赖关系

时间:2015-01-18 22:41:22

标签: c# asp.net asp.net-web-api

我在尝试在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

2 个答案:

答案 0 :(得分:1)

根据我的经验,当我看到此消息时,通常某些依赖项无法构建或缺少依赖项。你有IPostRepository注册到PostRepository,所以看起来不错。在PostRepository中创建的SqlConnection怎么样?您是否可以仅针对存储库运行一些测试代码,以查看它是否自行构建好了?

另外,在浏览代码时,是否检查阻止您在UnityResolver类中解析IPostRepository的接口?

    if (serviceType.IsAbstract || serviceType.IsInterface)
    {
        return null;
    }

答案 1 :(得分:0)

以下link有一个基于您提到的相同教程的工作项目。

与您的代码差别不大,除了数据库将以localdb为目标,而在UnityResolver上没有对Abstract类的检查,我认为这没有任何区别。

现在,您可以将项目用作启动点来添加逻辑,并确切知道它何时失败以及原因。

希望这会有所帮助。