Атрибуты инъекций и инъекций зависимостей - PullRequest
0 голосов
/ 12 сентября 2018

Я использую Ninject:

public static class NinjectWebCommon
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start()
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        var resolver = new NinjectSignalRDependencyResolver(kernel);
        try
        {
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            GlobalHost.DependencyResolver = new NinjectSignalRDependencyResolver(kernel);

            RegisterServices(kernel);

            GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);

            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<TMS.Entities.AssetContext>().ToSelf().InRequestScope();
        kernel.Bind<TMS.Data.IDbContext>().To<TMS.Entities.AssetContext>().InRequestScope();
        kernel.Bind(typeof(TMS.Data.IRepository<>)).To(typeof(TMS.Data.EfRepository<>));

        kernel.Bind<IExportManager>().To<ExportManager>().InRequestScope();
        kernel.Bind<IDriverService>().To<Services.Drivers.DriverService>().InRequestScope();
        .....
    }
}

Работает нормально для контроллеров Mvc и Api. Но сейчас я пишу ActionFilter:

public class AccessLoadApiAttribute : ActionFilterAttribute
{
    public AccessLoadApiAttribute()
    {

    }

    private readonly ILoadServiceEntity _loadServiceEntity;
    public AccessLoadApiAttribute(ILoadServiceEntity loadServiceEntity)
    {
        _loadServiceEntity = loadServiceEntity ?? throw new ArgumentNullException(nameof(loadServiceEntity));
    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var loadId = Convert.ToInt32(actionContext.RequestContext.RouteData.Values["Id"]);
        _loadServiceEntity.GetLoadById(loadId);

        base.OnActionExecuting(actionContext);
    }
}

и _loadServiceEntity равно нулю. Что не так в настройке?

1 Ответ

0 голосов
/ 12 сентября 2018

В Asp.Net Web API 2.x атрибуты не допускают внедрения зависимостей через конструктор, если вы хотите использовать их для отдельных действий.

Вы должны будете использовать анти-шаблон локатора службы через IDependencyResolver, к которому можно получить доступ через HttpConfiguration

Например

public class AccessLoadApiAttribute : ActionFilterAttribute {

    public override void OnActionExecuting(HttpActionContext actionContext) {
        //get the resolver via the request context
        var resolver = actionContext.RequestContext.Configuration.DependencyResolver;
        //use resolver to get dependency
        ILoadServiceEntity _loadServiceEntity = (ILoadServiceEntity)resolver.GetService(typeof(ILoadServiceEntity));
        var loadId = Convert.ToInt32(actionContext.RequestContext.RouteData.Values["Id"]);
        _loadServiceEntity.GetLoadById(loadId);
        base.OnActionExecuting(actionContext);
    }
}

Атрибут теперь можно использовать по мере необходимости

[AccessLoadApi]
[HttpGet]
public IHttpActionResult SomeGetAction() {
    return Ok();    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...