【问题标题】:Webapi 2 controllers on 2 projects2 个项目上的 Webapi 2 个控制器
【发布时间】:2017-02-10 05:25:32
【问题描述】:

我有一个 webapi2 C# 项目,所有控制器都在一个控制器文件夹中。 我现在有一些我想添加的功能,但我想将它放在一个不同的 Visual Studio 项目中,该项目将拥有自己的控制器(以及模型和视图)文件夹。这是否可能,以便我可以创建某种将由 webapi2 加载的模块?

【问题讨论】:

  • 1) 将所有控制器放入 web 项目中,并让这些控制器调用不同的服务(位于另一个项目中)。很少,甚至没有逻辑(除了异常处理/日志记录)应该在你的控制器中。他们应该叫另一个班级来做这项工作。 2)在iis下创建两个独立的应用程序,并构建一个新的api。

标签: c# visual-studio asp.net-web-api asp.net-web-api2


【解决方案1】:

Web Api 依赖 IHttpControllerSelector 来选择处理请求的 api 控制器,其默认实现依赖于 IAssembliesResolver 来解析程序集以搜索 api 控制器。

在最少的更改中,您可以将此程序集解析器替换为自定义实现,该实现将为您加载其他库。

一个非常幼稚的例子可能如下所示:

public class CustomAssemblyResolver : IAssembliesResolver
{
    public List<string> PluginNames { get; set; }

    public CustomAssemblyResolver()
    {
        PluginNames = new List<string>();

        //Add the custom libraries here
        PluginNames.Add("Your_Second_Library");
    }

    public ICollection<Assembly> GetAssemblies()
    {
        var asms = AppDomain.CurrentDomain.GetAssemblies().ToList();
        foreach (var name in PluginNames)
        {

            var asmPath = System.IO.Path.Combine(HostingEnvironment.MapPath("~/"), name + ".dll");
            try
            {
                var asm= System.Reflection.Assembly.LoadFrom(asmPath);
                if(!asms.Contains(asm))
                    asms.Add(asm);
            }
            catch (Exception)
            {

            }
        }
        return asms;
    }
}

然后您可以使用此代码替换默认解析器

config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());

WebApiConfig 类的 Register 方法中。

然后,将所有带有控制器类的附加库复制到 bin 目录,就完成了。

如果您需要进一步自定义控制器选择,您可以自定义实现 IHttpControllerSelector 并以类似方式替换现有实现。

【讨论】:

    【解决方案2】:

    您可以在库项目中创建功能,然后将该项目引用到您的 webapi2 和其他 Visual Studio 项目。基本上你会有三个解决方案;两个 webapi 解决方案和一个库解决方案。库解决方案将包含两个 webapi 解决方案所需的逻辑。

    【讨论】:

      【解决方案3】:

      您不应该在两个项目中都需要控制器。

      如果控制器用于完全不同的业务域,请在带有两个解决方案的 IIS 中创建两个 api。

      如果它们相似,请在 Web 项目中创建所有控制器。然后让这些控制器调用单独的应用程序服务。

      public CustomerAccountsController : ApiController
      {
          private CustomerAccountService _customerAccountService; // lives in application layer project
          public CustomerAccountsController() 
          { 
              // di stuff 
          }
      
          public HttpResponseMessage PutCancelAccount( int accountId )
          {
             // exception handling + logging
             _customerAccountService.CancelAccount(accountId);
      
            // return status code if success, or if an exception
          }
      }
      
      public OrderController : ApiController
      {
          private OrderService _orderService; // lives in application layer project
          public OrderController()
          { //di stuff
          }
      
          public HttpResponseMessage PostCreateOrder(CreateOrderRequest createOrderRequest) 
          {
              // exception handling + logging
              _orderService.TakeOrder(createOrderRequest);
      
              // return status code if success, or if an exception
          }
      }
      

      因此,您的大部分逻辑应该隐藏在应用层服务之后,并且这些服务应该具有将 1-1 映射到用例的方法。如果这两个应用程序的业务域完全不同,只需创建两个单独的解决方案和两个单独的 IIS 应用程序/api

      【讨论】:

      • 你也可以考虑Area的。 Web Api 也有,对吧?
      【解决方案4】:

      不,这是不可能的。您最多可以创建一个将编译为 DLL 的类库,然后在您的 WebApi 中引用该 DLL。否则,您将不得不将所有内容放在同一个应用程序 (WebApi) 中或创建两个不同的 WebApi 应用程序。

      【讨论】:

        【解决方案5】:

        根据您的需要...

        我的建议是,只需将 2 个控制器放在一个项目中,然后在您的其他项目中创建一个帮助程序/服务文件夹/类,并在需要时调用这些服务。

        这并不是您问题的真正答案,但我相信这会有所帮助。通常我们使用这种文件夹结构创建一个解决方案,我希望这会有所帮助:

        MyTeamSolution
            - MyTeam.Core   = Class libraries
                > Models
                    > Model1.cs
                    > Model2.cs 
                    > Model3.cs
                > Interface
                    > ISomeInterface.cs
                > Helpers
                    > HelperClass.cs
        
            - MyTeam.Api    = webapi project
                > Model1Controller.cs
                > Model2Controller.cs
                > Model3Controller.cs
            - MyTeam.Web    = mvc project
                > Controllers
                > Models
                > Views
                > etc. 
            - MyTeam.Sql    = Class libraries
                > MyTeamDbContext.cs
        

        【讨论】:

          猜你喜欢
          • 2013-10-09
          • 1970-01-01
          • 2019-06-08
          • 1970-01-01
          • 1970-01-01
          • 2014-10-29
          • 1970-01-01
          • 2015-01-16
          • 1970-01-01
          相关资源
          最近更新 更多