1

私はドキュメントを読んできましたが、私はこれをどのように達成するか少し混乱しています。 NewsControllerという名前のWebAPIコントローラがあります。それは現在3つの依存関係を取る単一のコンストラクタを持っています。 DryIoc用の静的クラスを作成しましたので、プロジェクト全体でグローバルに使用でき、起動時に初期化されます。WebAPIコントローラとDryIocの依存関係を解決する方法

私がしたいことは、コントローラを自分の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を使用して自動的に依存関係を登録および解決するコードが表示されます。 DryIocとNuGetのDryIoc.WebAPIパッケージを使用する必要があります。

テスト実装をスワップアウトするには、テスト/モック依存関係のクラスを作成する必要があります。上記ののRegisterDependenciesを使用することもできますが、本番実装の代わりにスタブまたはモックを登録することができます。

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>(); 

     } 


    } 
} 

その後(私はxUnitフレームを使用しています)、あなたのテストクラスは、コンストラクタでAutoMapperセクションの心配はありません。このかかわらのようになります。

関連する問題