Как установить Web API DependencyResolver при использовании MVVMLight - PullRequest
0 голосов
/ 04 января 2019

Я использую OWIN для самостоятельного размещения веб-службы веб-API в настольном приложении wpf, которое использует инфраструктуру galasoft mvvmlight.Когда я пытаюсь ввести зависимости в один из моих сервисов данных модели в контроллер веб-API, я получаю сообщение об ошибке «Убедитесь, что у контроллера есть открытый конструктор без параметров».

Я понимаю, что контроллер веб-API не будет поддерживать внедрение зависимостей из коробки.Я видел множество примеров, подробно описывающих, как предоставить пользовательский IDependencyResolver при использовании Unity или написать свой собственный.Есть ли прямой способ установить свойство DependencyResolver класса запуска веб-API HttpConfiguration объекта, используя mvvmlight SimpleIoc.Default?

В качестве обходного пути, я в настоящее время устанавливаю службу данных, вызывая SimpleIoc.Default.GetInstance() вмой конструктор контроллера API.Это работает и может быть функционально таким же, как полагаться на механизм внедрения, но внедрение зависимости кажется более элегантным.

public class webApiStartup {
    public void Configuration(IAppBuilder appBuilder)
    {
        // Configure Web API for self-host. 
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            name: "FileServerApi",
            routeTemplate: "{controller}/{filename}"
            ,defaults: new { Controller = "filesController" }
        );
//*
//* The Following line of Code does not work. But intellisense suggests
//* that there is a conversion available ?
//*
        config.DependencyResolver = (IDependencyResolver)SimpleIoc.Default;

        appBuilder.UseWebApi(config);
    }
}

//*
//* This constructor for the web api controller works
//* but it is not as elegant as dependency injection
//*
public class filesController : ApiController
{
    ILocalDataService _LocalDataSvc = null;

    public filesController() {
        _LocalDataSvc = SimpleIoc.Default.GetInstance<ILocalDataService>();
    }

1 Ответ

0 голосов
/ 04 января 2019

Приведение

 config.DependencyResolver = (IDependencyResolver)SimpleIoc.Default;

завершится неудачей, поскольку SimpleIoc не получено из IDependencyResolver.

Создайте оболочку для контейнера, полученного из IDependencyResolver

public class SimpleIocResolver : IDependencyResolver {
    protected ISimpleIoc container;

    public SimpleIocResolver(ISimpleIoc container) {
        if (container == null) {
            throw new ArgumentNullException("container");
        }
        this.container = container;
    }

    public object GetService(Type serviceType) {
        try {
            return container.GetInstance(serviceType);
        } catch(Exception) {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        try {
            return container.GetAllInstances(serviceType);
        } catch (Exception) {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope() {
        return new SimpleIocResolver(container);
    }

    public void Dispose() {
        //No Op
    }
}

и используйте это при настройке

config.DependencyResolver = new SimpleIocResolver(SimpleIoc.Default);

Затем можно выполнить рефакторинг ApiController

public class FilesController : ApiController {
    ILocalDataService _LocalDataSvc = null;

    public FilesController(ILocalDataService svc) {
        _LocalDataSvc = svc;
    }

    //...

при условии, что зависимости были зарегистрированы в контейнере.

Ссылка Внедрение зависимостей в ASP.NET Web API 2

...