2017-04-17 2 views
2

WebApi 2.0のすべてのコントローラを含むコントローラアセンブリを作成し、この記事の後に - https://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/を作成し、CustomAssemblyResolverを作成し、Application_Startのアセンブリリゾルバを置き換えるコードを追加しました。WebApi 2 AssemblyResolver

マイCustomAssemblyResolver:ここでは私のコードは次のようになります。

public class CustomAssemblyResolver : DefaultAssembliesResolver 
{ 
    public override ICollection<Assembly> GetAssemblies() 
    { 
     ICollection<Assembly> baseAssemblies = base.GetAssemblies(); 
     List<Assembly> assemblies = new List<Assembly>(baseAssemblies); 

     string thirdPartySource = "C:\\Research\\ExCoWebApi\\ExternalControllers"; 

     if (!string.IsNullOrWhiteSpace(thirdPartySource)) 
     { 
      if (Directory.Exists(thirdPartySource)) 
      { 
       foreach (var file in Directory.GetFiles(thirdPartySource, "*.*", SearchOption.AllDirectories)) 
       { 
        if (Path.GetExtension(file) == ".dll") 
        { 
         var externalAssembly = Assembly.LoadFrom(file); 

         baseAssemblies.Add(externalAssembly); 
        } 
       } 
      } 
     } 
     return baseAssemblies; 
    } 
} 

私のApplication_Start:

protected void Application_Start() 
    { 
     Debugger.Launch(); 

     AreaRegistration.RegisterAllAreas(); 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 

     GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());    


    } 

あなたは私がCustomAssemblyResolverと、デフォルトのアセンブリリゾルバを交換しています見ることができるように。ここで

は、私は、サードパーティのコントローラにルートを登録しています方法は次のとおりです。

public static void RegisterRoutes(RouteCollection routes) 
    {    
     routes.MapHttpRoute(
      name: "Test", 
      routeTemplate: "api/thirdparty/math", 
      defaults: new { controller = "Math" } 
     );    
    } 

これは、それが別のアセンブリに住んでいるように私のMathControllerがどのように見えるかです:

public class MathController : ApiController 
{ 
    [HttpPost] 
    public int AddValues(MathRequest request) 
    { 
     int response = MathOperations.Add(request.Value1, request.Value2); 
     return response; 
    } 
} 

これは、エンドポイントIでありますpostman:http://localhost/ExCoWebApi/api/thirdparty/mathでBodyにPOST操作とMathRequest JSON文字列を打つと、これが応答として返されます:

{ "Message": "リクエストURI 'http://localhost/ExCoWebApi/api/thirdparty/math'に一致するHTTPリソースが見つかりませんでした。"、 "MessageDetail": "'Math'というコントローラに一致するタイプが見つかりませんでした。 }

デバッグ後、AssemblyResolverがアプリケーション起動時にCustomAssemblyResolverに置き換えられますが、CustomAssemblyResolverのGetAssemblies()メソッドが呼び出されないという問題がありました。したがって、MathControllerを含むアセンブリはロードされません。

私はここで何が欠けていますか?

EDIT

これに対する解決策を見つけることに必死の努力の中で、私は私自身のHttpConfigurationオブジェクトを構築し、それにAssemblyResolverを交換する試験方法を立ち上がって、それが魔法のように動作します! CustomAssemblyResolverのGetAssemblies()関数が呼び出され、私は外部コントローラを呼び出すことができます。 "GlobalConfiguration.Configuration"から返されるHttpConfigurationオブジェクトと、手動でインスタンス化するのに違いがあるのでしょうか?これは非常に高く評価されます。

[TestMethod] 
    public void TestExternalControllerCall() 
    { 
     try 
     { 
      HttpClient client = GetClient(); 
      MathRequest mathReq = new MathRequest { Value1 = 10, Value2 = 20 }; 
      var response = client.PostAsJsonAsync(string.Concat("http://localhost/api/thirdparty/math"), mathReq).Result; 
      var entResponse = response.Content.ReadAsAsync<int>().Result; 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex); 
     } 
    } 

    private HttpClient GetClient() 
    {    
     HttpConfiguration config = new HttpConfiguration(); 
     config.Routes.MapHttpRoute(
      name: "Test", 
      routeTemplate: "api/thirdparty/math", 
      defaults: new { controller = "Math" } 
     ); 
     config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver()); 
     HttpServer server = new HttpServer(config); 
     HttpClient client = new HttpClient(server); 
     return client;   
    } 

答えて

1

が問題を発見:ここに私のテストメソッドのコードです

GetAssemblies()が呼び出さ取得されなかった理由であるため、GlobalConfiguration.Configureに設定されたコールバックメソッド(WebApiConfig.Register)が"config.MapHttpAttributeRoutes();"を呼び出していました。 The

GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver)、new CustomAssemblyResolver());

コードは、GlobalConfiguration.Configureにコールバックが設定されている場合は、Global.asaxではなく、GlobalConfiguration.Configureで構成されたコールバックメソッドに実際に属します。そこで、WebApiConfigのRegisterメソッドにIAssemblyResolver replaceステートメントを移しました。

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver()); 

     // Web API routes 
     config.MapHttpAttributeRoutes();    
    } 
} 
関連する問題