【问题标题】:web api self host custom ioc inject data to controllersweb api 自托管自定义 ioc 将数据注入控制器
【发布时间】:2015-12-31 03:43:32
【问题描述】:

我的 web api 自托管应用程序中有一个属性,我想将它注入到我的控制器中,该属性是使用我的自定义 IoC 框架通过反射加载的,这是我的启动代码:

public CustomClass StuffInstance { get; set; }


// This method is required by Katana:
public void Configuration(IAppBuilder app)
{
    ConfigureOAuth(app);
    var webApiConfiguration = ConfigureWebApi();

    // Use the extension method provided by the WebApi.Owin library:
    app.UseWebApi(webApiConfiguration);
}

我的控制器大多是脚手架,有些像:

// PUT: api/EventTypeDescriptions/5
[ResponseType(typeof(void))]
public IHttpActionResult PutStuff(int id, int something)
{
    //do stuff
    //here i would like to use StuffInstance like a singleton
    return StatusCode(HttpStatusCode.NoContent);
}  

如何将 StuffInstance 注入我的控制器?顺便说一句,此信息将与任何制作 IoC 框架的人相关

【问题讨论】:

  • 您的 IoC 使用什么?您需要将 IoC 解析器分配给配置,并创建一个代表 CustomClass 的接口。
  • 它是一个自定义的东西,但我可能正在考虑使用 autofac,我可以使用我的自定义解析器以某种方式注入实例吗?
  • 用什么没关系;你只需要使用一些东西。你必须注册你的控制器并在他们被请求时为它们解决依赖关系,而你在这里没有做任何类似的事情。
  • 我赞成您建议我使用接口的评论,但我仍然不知道如何将实例注入我的控制器,有任何信息吗?也许是我需要阅读的信息的链接?
  • 我为您添加了一个 AutoFac 示例。希望对您有所帮助!

标签: c# asp.net-web-api inversion-of-control ioc-container self-hosting


【解决方案1】:

我在此链接中找到了将实例注入我的控制器的信息:

http://www.asp.net/web-api/overview/advanced/dependency-injection

基本上我为我的自定义 IoC 库实现了一个依赖解析器

如果有人遇到同样的问题,这里是代码,也许对于其他 IoC 框架它需要更多的工作

public class CustomIocDependencyResolver : IDependencyResolver
{
    private readonly CustomIoc container;

    public ComponentLoaderWebApiDependencyResolver(CustomIoc container)
    {
        this.container = container;
    }

    IDependencyScope IDependencyResolver.BeginScope()
    {
        return new CustomIocDependencyResolver(container);
    }

    Object IDependencyScope.GetService(Type serviceType)
    {
        return container.GetInstance(serviceType);
    }

    IEnumerable<Object> IDependencyScope.GetServices(Type serviceType)
    {
        return container.GetAllInstances(serviceType);
    }

    public void Dispose()
    {
    }
}

现在我的武士刀配置如下:

    // This method is required by Katana:
    public void Configuration(IAppBuilder app)
    {
        ConfigureOAuth(app);
        var config = ConfigureWebApi();

        config.DependencyResolver = CustomIocDependencyResolver(container);

        // Use the extension method provided by the WebApi.Owin library:
        app.UseWebApi(config);
    }

作为我的自定义 IoC 实例的容器

【讨论】:

    【解决方案2】:

    由于您提到 AutoFac 作为潜在候选者,我建议您关注他们的 tutorial 关于 WebAPI 集成。您需要在 CustomClass 上定义一个接口,以便正确注入它。

    您需要通过将其注册为实例组件来注入您创建的实例(因为您希望将其视为单例)。

    public interface ICustomClass {}
    public class CustomClass : ICustomClass {}
    
    public CustomClass _stuffInstance = new CustomClass();
    
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureOAuth(app);
    
            var builder = new ContainerBuilder();
            var config = new HttpConfiguration();
    
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    
            builder.RegisterInstance(_stuffInstance).As<ICustomClass>();
    
            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    
            app.UseAutofacMiddleware(container);
            app.UseAutofacWebApi(config);
            app.UseWebApi(config);
        }
    }
    

    然后,在每个控制器的构造函数中,注入绑定到相应接口的实例。

    public class CustomController : ApiController
    {
        private readonly ICustomClass _customClass;
    
        public CustomController(ICustomClass customClass)
        {
            _customClass = customClass;
        }    
    }
    

    【讨论】:

      【解决方案3】:

      使用 ASP.NET Core 6,您现在可以注册服务提供者:

      builder.Services.AddScoped<ICustomClass, CustomClass>(sp => new CustomClass()/* or your already existing instance */);
      builder.Services.AddSingleton<ICustomClass>(sp => new CustomClass()/* or your already existing singleton instance */);
      

      它将被注入到您的控制器中:

      [Route("api/[controller]")]
      [ApiController]
      public class MyController : ControllerBase
      {
          private readonly ICustomClass _customClass;
          private readonly ILogger _logger;
      
          public MyController(ICustomClass customClass, ILogger<MyController> logger)
          {
              _customClass = customClass;
              _logger = logger;
          }
      

      【讨论】:

      • 谢谢,这在我升级时会有用!
      猜你喜欢
      • 2016-05-03
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-18
      • 2021-10-31
      • 1970-01-01
      相关资源
      最近更新 更多