Как разрешить зависимость в конструкторе веб-API в ядре .NET

Я новичок в концепции ядра .net и инъекции зависимостей. Я хочу внедрить интерфейс службы в конструктор веб-API, интерфейс службы и реализация находятся в другом проекте. Пожалуйста, найдите ниже уровни моего приложения,

Уровни приложения

В startup.cs я уже добавил строку ниже,

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddSingleton<IEntriesService, EntriesService>();
}

Мой контроллер,

public class EntriesController : Controller
{
    IEntriesService entryService;
    public EntriesController(IEntriesService _entryService)
    {
        entryService = _entryService;
    }

    // GET: api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

Проблема в том, что когда я выполняю свое приложение API, оно не попадает в мой конструктор и показывает мне пустую страницу, как показано ниже,

Страница ошибки

Без добавления конструктора приложение работает нормально.

Мой IEntriesService,

public interface IEntriesService
{
    RepeatEntries Get(int Id);
}

My EntriesService,

public class EntriesService : IEntriesService
{
    IUnitOfWork _unitOfWork;
    public EntriesService(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public bool Add(RepeatEntries entity)
    {
        _unitOfWork.EntryRepository.Add(entity);
        return true;
    }
}

Мой IUnitOfWork,

public interface IUnitOfWork : IDisposable
{
    IEntriesRepository EntryRepository { get; }
    void Complete();
}

Мой UnitOfWork,

public class UnitOfWork : IUnitOfWork
{
    private readonly IEntriesRepository _entryRepository;
    public UnitOfWork(IEntriesRepository entryRepository)
    {
        _entryRepository = entryRepository;
    }

    public IEntriesRepository EntryRepository
    {
        get
        {
            return _entryRepository;
        }
    }

    void IUnitOfWork.Complete()
    {
        throw new NotImplementedException();
    }

    #region IDisposable Support
    private bool disposedValue = false; // To detect redundant calls



    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                // TODO: dispose managed state (managed objects).
            }

            // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
            // TODO: set large fields to null.

            disposedValue = true;
        }
    }

    // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
    // ~UnitOfWork() {
    //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
    //   Dispose(false);
    // }

    // This code added to correctly implement the disposable pattern.
    void IDisposable.Dispose()
    {
        // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
        Dispose(true);
        // TODO: uncomment the following line if the finalizer is overridden above.
        // GC.SuppressFinalize(this);
    }
    #endregion
}

Что еще мне нужно добавить, чтобы он заработал? Возможно ли это или мне нужно изменить свой подход?


person Keval Patel    schedule 01.05.2017    source источник
comment
500 - внутренняя ошибка сервера. Просто нажмите F5 (начните с отладки) и посмотрите, что это за исключение. Ваш подход правильный и нет причин не работать.   -  person regnauld    schedule 01.05.2017
comment
Отладчик обращается к программным и стартовым классам, но не к конструктору контроллера. И обновите показ той же страницы.   -  person Keval Patel    schedule 01.05.2017
comment
Вам необходимо предоставить дополнительную информацию, если вы ожидаете, что мы поможем вам, не используя наши всемогущие навыки гадания. Вы только разместили содержимое своего контроллера, но как насчет вашего EntriesService? Мы понятия не имеем, есть ли у него какие-либо зависимости, и зарегистрированы ли вы их или нет.   -  person Tseng    schedule 01.05.2017
comment
Проблема может быть в вашем Startup классе, поэтому он не попадает в ваш контроллер. Вы можете добавить диагностическое промежуточное ПО в начало конвейера, чтобы каждый раз при возникновении необработанного исключения вы видели страницу исключения с подробностями и трассировкой стека. Для этого добавьте пакет nuget в свой проект Microsoft.AspNetCore.Diagnostics, а затем добавьте app.UseDeveloperExceptionPage() в начало метода Startup.Configure(). Надеюсь, это даст вам больше подробностей о том, что происходит.   -  person Alexey Andrushkevich    schedule 01.05.2017
comment
Пожалуйста, ознакомьтесь с измененным вопросом с дополнительным описанием   -  person Keval Patel    schedule 01.05.2017
comment
Да, выдает ошибку ниже: InvalidOperationException: невозможно разрешить службу для типа Breakout.Service.UnitOfWork.IUnitOfWork при попытке активировать Breakout.Service.Services.EntriesService.   -  person Keval Patel    schedule 01.05.2017
comment
Вы где-нибудь регистрируете IUnitOfWork для DI? Если нет, вы должны, иначе MVC не сможет построить иерархию.   -  person regnauld    schedule 01.05.2017
comment
@KevalPatel вы должны зарегистрировать все зависимости в корне композиции. Как еще он мог бы знать, как разрешать типы.   -  person Nkosi    schedule 01.05.2017
comment
Хорошо, понял, последний вопрос, могу ли я зарегистрировать все зависимости в приложении API или мне нужно разделить их на основе проектов?   -  person Keval Patel    schedule 01.05.2017
comment
@KevalPatel, который в первую очередь основан на мнении. Вы можете сделать это в любом случае.   -  person Nkosi    schedule 01.05.2017


Ответы (1)


Вы должны зарегистрировать все зависимости в корне композиции, убедившись, что зарегистрировали их с правильным временем жизни, то есть: (_ 1_, Transient, Singleton), чтобы избежать проблем в будущем.

public void ConfigureServices(IServiceCollection services) {
    // Add framework services.
    services.AddMvc();

    services.AddSingleton<IEntriesService, EntriesService>();
    services.AddTransient<IUnitOfWork, UnitOfWork>();
    services.AddTransient<IEntriesRepository, EntriesRepository>();
    services.AddSingleton<IConnectionFactory, ConnectionFactory>();

    //...add other dependencies. 
}

Найдите время и ознакомьтесь с документацией:

Введение в внедрение зависимостей в ASP.NET Core

person Nkosi    schedule 01.05.2017