1

我一直在阅读文档,对于如何实现这一点我有点困惑。我有一个名为NewsController的WebAPI控制器,我将在下面列出。它有一个构造函数,目前需要三个依赖项。我为DryIoc创建了一个静态类,因此我可以在整个项目中全局使用它,并在启动时进行初始化。如何使用DryIoc解决WebAPI控制器的依赖关系

我想要做的就是将控制器及其依赖关系注册到我的DryIoc类中,然后以某种方式在NewsController控制器中解决该问题。我想这样做的原因是,当我开始测试时,我可以简单地让测试项目更改注册控制器的范围,并使用存根或模拟实现。

RegisterDependencies

public static class RegisterDependencies 
    { 
     public static Container container; 

    public static void Initialize() 
    { 
     container = new Container(rules => rules 
     .WithDefaultReuseInsteadOfTransient(Reuse.InWebRequest) 
     .WithoutThrowOnRegisteringDisposableTransient() 
     .WithoutImplicitCheckForReuseMatchingScope()); 

     container.Register<INewsManager, NewsManager>(); 
     container.Register<IGetNews, NewsManager>(); 
     container.Register<IAddNews, NewsManager>(); 

     container.Register<ILoggingService, Logger>(); 

     container.Register<NewsController>(made: Made.Of(() => new NewsController 
      (Arg.Of<ILoggingService>(), Arg.Of<IGetNews>(), Arg.Of<IAddNews>(), 
      Arg.Of<INewsManager>()))); 
    } 
} 

NewsController(它的一部分反正)

public class NewsController : ApiController 
    { 
     private INewsManager _nm; 
     private IGetNews _getNews; 
     private IAddNews _addNews; 
     private ILoggingService _log; 

    public NewsController(ILoggingService logger, IGetNews getNews, 
     IAddNews addNews, INewsManager newsManager) 
    { 
     _getNews = getNews; 
     _addNews = addNews; 
     _log = logger; 
     _nm = newsManager; 
    } 

    [HttpGet] 
    public IHttpActionResult GetNews() 
    { 

     var newsItems = _getNews.GetNews(); 

     if (newsItems == null || newsItems.Count() <= 0) 
     { 
      _log.Error("News Items couldn't be loaded."); 

      return NotFound(); 
     } 



     return Ok(Mapper.Map<List<NewsDto>>(newsItems)); 
    } 

UPDATE:

到目前为止,我有 “自动” 依赖分辨率经历WebApiConfig但是我我不确定如何从测试项目访问这个,所以我可以用我的存根替换真正的实现。

WebApiConfig

public static void Register(HttpConfiguration config) 
     { 
     // Web API configuration and services 
     config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); 

     // Web API routes 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

     RegisterDependencies.controllerContainer = new Container(rules => rules.With(FactoryMethod.ConstructorWithResolvableArguments)).WithWebApi(
      config, throwIfUnresolved: type => type.IsController()); 
     RegisterDependencies.InitializeControllerContainer(RegisterDependencies.controllerContainer); 

     } 

RegisterDependencies

public static class RegisterDependencies 
    { 
     public static IContainer controllerContainer; 

     public static void InitializeControllerContainer(IContainer ControllerContainer) 
     { 

      ControllerContainer.RegisterMany<ILoggingService, Logger>(setup: Setup.With(allowDisposableTransient: true)); 
      ControllerContainer.RegisterMany<INews, NewsManager>(setup: Setup.With(allowDisposableTransient: true)); 
     } 

NewsController

public class NewsController : ApiController 
    { 
     private INews _news; 
     private ILoggingService _log; 

     public NewsController(INews news, ILoggingService logger) 
     { 
      _news = news; 
      _log = logger; 
     } 

回答

1

好吧,他重新是我想出的。

在上面的问题更新:你会看到代码将自动注册和解决使用WebAPIConfig的依赖关系。你需要使用NuGet的DryIoc.WebAPI包以及DryIoc。

为了能够替换测试实现,您需要为测试/模拟依赖关系创建一个类。您可以仅使用RegisterDependencies以上,但注册您的存根或模拟而不是生产实现。

那么你的测试类(我用的xUnit)将是这个样子,虽然不用担心在构造函数中AutoMapper部分:

public class NewsControllerTests 
    { 
     private IContainer _testContainer; 
     private NewsController _controller; 

     public NewsControllerTests() 
     { 
      Mapper.Initialize(config => 
      { 
       config.CreateMap<News, NewsDto>(); 
       config.CreateMap<NewsDto, News>(); 
      }); 

      _testContainer = RegisterTestDependencies.testContainer = new Container(rules => rules.With(FactoryMethod.ConstructorWithResolvableArguments)).WithWebApi(
       new HttpConfiguration(), throwIfUnresolved: type => type.IsController()); 

      RegisterTestDependencies.InitializeTestContainer(_testContainer); 

     } 

     [Fact] 
     void GetNews_WithoutId_ReturnsAllNewsItems() 
     { 
      //Arrange 

     using (var scope = _testContainer.OpenScope(Reuse.WebRequestScopeName)) 
     { 
      _controller = scope.Resolve<NewsController>(); 

      //Act 

      var getNewsResult = _controller.GetNews() as OkNegotiatedContentResult<List<NewsDto>>; 

      //Assert 

      getNewsResult.Content.Should().AllBeOfType<NewsDto>(); 

     } 


    } 
} 
相关问题