【问题标题】:Using unity DI in both web api and class library在 web api 和类库中使用统一 DI
【发布时间】:2017-01-09 12:21:06
【问题描述】:

我正在创建一个新的 web api 项目。除了 web api 项目,我还使用了另外两个类库项目,如下所示:

MyBlog.API (Web API project)
MyBlog.Services (Class library)- Contains additional business logic
MyBlog.Repositories (Class library) - contains all database related operations

在 API 项目中,我添加了 Services 项目的引用,在 Services 项目中,我添加了 Repositories 项目的引用,因此 API 将调用服务,服务将调用存储库,如下所示:

API > Services > Repositories

我不想直接从我的 api 控制器调用存储库,它们将通过服务调用。所以我没有在 api 项目中添加存储库项目引用。

现在我正在我的 api 项目中实现 unity.webapi 依赖注入。下面是实现DI的代码:

存储库代码:

namespace MyBlogs.Repositories
{
    public interface ITestRepository
    {
        string Get();
    }
}

namespace MyBlogs.Repositories
{
    public class TestRepository:ITestRepository
    {
        public string Get()
        {
            return "test";
        }
    }
}

带有 DI 实现的服务代码:

namespace MyBlogs.Services
{
    public interface ITestService
    {
        string Get();
    }
}

namespace MyBlogs.Services
{
    public class TestService : ITestService
    {
        private ITestRepository testRepository;

        public TestService(ITestRepository testRepositoryParam)
        {
            this.testRepository = testRepositoryParam;
        }

        public string Get()
        {
            return this.testRepository.Get();
        }
    }
}

控制器代码:

public class ValuesController : ApiController
    {
        private ITestService testService;
        public ValuesController(ITestService testServiceParam)
        {
            this.testService = testServiceParam;
        }

        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { this.testService.Get() };
        }
}

最后是 unityconfig 文件:

public static class UnityConfig
    {
        public static void RegisterComponents()
        {
            var container = new UnityContainer();
            container.RegisterType<ITestService, TestService>();

            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
        }
    }

现在我在这里面临这个问题,因为我没有在我有这个 unityconfig 文件的 api 项目中添加存储库项目引用,所以我如何在统一中注册 ITestRepository 和 TestRepository,类似于 ITestService 和 TestService?有什么方法可以在不添加项目引用的情况下在其他地方注册我的存储库项目的依赖项?或者如果我将尝试在服务项目中添加统一性,那么它将如何注册??

我已经在web api项目的global.asax中注册了unityConfig:

protected void Application_Start()
        {
            UnityConfig.RegisterComponents();
        }

【问题讨论】:

  • mmm .. 我认为您必须在 webapi 项目或控制台项目中调用 Unity ..
  • 理论上你可以在 MyBlogs.Services 程序集中定义另一个 Unity 配置,它知道存储库并注册它。这样做你不会有从 webapi 到存储库的引用使 MyBlogs.Services 中的另一个 UnityConfig 在那里注册你的存储库类型,然后 ServicesUnityConfig.RegsiterComponents() UnityConfig.RegisterComponents();
  • @eranotzap 看起来不错,我会试一试。谢谢。

标签: asp.net-mvc asp.net-web-api unity-container


【解决方案1】:

这是一个很好的问题,我自己并没有团结一致地做到这一点。 Autofac、Windsor 和其他 DI 允许您从每个程序集公开模块或安装程序,然后您从引用它们的其他程序集加载模块。

所以我将根据这个想法提出一个通用的解决方案。 (希望这可以工作:))

public static class WebApiUnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        container.RegisterType<ITestService, TestService>();

        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}   


public static class ServicesUnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        container.RegisterType<ITestRepository, TestRepository>();

        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}   


protected void Application_Start()
{
     ServiceUnityConfig.RegisterComponents();
     WebApiUnityConfig.RegisterComponents();
}

【讨论】:

  • 根据您的想法,我在服务项目中创建了一个统一文件,并通过将相同的 UnityContainer 作为参数传递给服务的统一文件,直接从 api 项目的统一文件调用其 RegisterComponents 方法,如下所示: 添加以下行在 api 项目的统一配置中:ServiceUnityConfig.RegisterComponents(container);
  • 以下是服务的统一配置文件:public static class ServiceUnityConfig { public static void RegisterComponents(UnityContainer container) { container.RegisterType();它解决了我的问题。谢谢。
  • 如果它解决了问题,你应该接受答案
  • 并没有真正“解决”问题,但确实让我们走上了真正的解决方案。
【解决方案2】:

我通过在服务项目中创建一个统一文件来解决它,并通过将相同的 UnityContainer 作为参数传递给服务的统一文件,直接从 api 项目的统一文件调用其 RegisterComponents 方法,如下所示:

public static class UnityConfig
{
    public static void RegisterComponents()
    {
    var container = new UnityContainer();

        container.RegisterType<ITestService, TestService>();
        ServiceUnityConfig.RegisterComponents(container);

        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}

public static class ServiceUnityConfig
{
    public static void RegisterComponents(UnityContainer container)
    {
        container.RegisterType<ITestRepository, TestRepository>();
    }
}

它解决了我的问题,而无需在 app_start 中注册两次 unity。感谢以上eran的回答,根据上面的回答我是这样实现的。

【讨论】:

  • 不得不说,这是迄今为止我遇到的最佳答案。我试图解决的问题是如何将引用从 api 项目解耦到存储库项目。由于类库中没有 main 或 app_start 的概念,如何实现呢?好吧,这行得通,在我找到更好的方法之前,这就是解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
相关资源
最近更新 更多