Веб-API самостоятельно размещать пользовательские данные ввода Ioc для контроллеров

У меня есть свойство в моем приложении, размещаемом в 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 Framework, кстати

3 ответа

Я нашел информацию для внедрения экземпляров в мои контроллеры по этой ссылке:

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

С 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;
    }

Поскольку вы упомянули AutoFac в качестве потенциального кандидата, я рекомендую вам следовать их руководству по интеграции с 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;
    }    
}
Другие вопросы по тегам