Веб-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;
}
}