Удаление объектов в WebAPI - PullRequest
       12

Удаление объектов в WebAPI

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

Я собираюсь сохранить одну существующую реализацию API.Когда я смотрю в код, я понял, что есть некоторые проблемы с удалением объекта.

Ниже приведен мой Базовый контроллер , который действует как родительский контроллер для всех.

[LoggingFilter]
[System.Web.Http.Authorize]
public abstract class BaseV1Controller : ApiController
{
    private ModelFactoryV1 _modelFactoryV1;
    private MyDBContext __db;
    private MyLoggingService _loggingService;
    private int _customerId;

    protected string __IPAddress;
    protected ILogger __logger;
    protected const int PAGE_SIZE_NORMAL = 20;
    protected const int PAGE_SIZE_MEDIA = 2;
    // GET: Base
    protected string __loggingResourceName = "Undefined - base controller";
    private void InitLogger()
    {
       Log.Logger.ForContext<BaseV1Controller>();
    }

    protected MyDBContext _db
    {
        get { return __db; }
        set { __db = value; }
    }

    public BaseV1Controller()
    {
        IEnumerable<string> values;
        __db = new MyDBContext();
        _loggingService = new MyLoggingService ();
        InitLogger();
    }

    public BaseV1Controller(MyDBContext db)
    {
        __db = db;
        _loggingService = new MyLoggingService ();
        InitLogger();
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        _loggingService = null;
    }

  }

Мы не переопределяем метод удаления в контроллере.В контроллере мы вызываем классы репозитория для выполнения операций CRUD.

Пример реализации ниже;

Контроллер:

   [LoggingFilter]
    [ValidateModel]
    [Authorize]
    public class CustomersV1Controller : BaseV1Controller
    {
        IAsyncRepository<Customer> _repo = new CustomerAsyncRepository();
        public CustomersV1Controller() : base()
        {
            _repo = new CustomerAsyncRepository();
        }

        public CustomersV1Controller(IAsyncRepository<Customer> repo, MyDBContext db) : base(db)
        {
            __loggingResourceName = "Customer";
            _repo = repo;
        }

       //All Actions implemented here

    }

РепозиторийИнтерфейс и класс:

    public interface IAsyncRepository<T>
    {

        Task<T> Add(T type);
        Task<T> Get(int Id);
        Task Update(T type);
    }

public class CustomerAsyncRepository : IAsyncRepository<Customer>
    {
        //saves the customer view models
        private MyDBContext _db { get; }

        public CustomerAsyncRepository(MyDBContext db)
        {
            this._db = db;
        }

        public CustomerAsyncRepository()
        {
            _db = new MyDBContext ();
        }

        public async Task<Customer> Add(Customer model)
        {
            //Add method implmementation
            return model;
        }

        public async Task<Customer> Get(int id)
        {
           //Implementation to return customer model
        }

        public async Task Update(Customer model)
        {
           //Implementation to update customer model
        }

    }

У меня есть следующее пояснение, основанное на этом

  1. Я думаю, что мы должны включить _db.Dispose () в метод dispose BaseV1Controller.В настоящее время я не могу реализовать шаблон DI.Пожалуйста, предложите?
  2. В репозитории ID не доступен.Это правильно?
  3. Есть ли другие улучшения?

1 Ответ

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

Да, вы должны утилизировать ваш DbContext в методе Dipose базового контроллера.В противном случае, никто не знает, что нужно утилизировать.В конечном итоге он может быть завершен через некоторое время после завершения запроса, но до тех пор, пока это не произойдет, базовое соединение с базой данных останется открытым и недоступным, что означает, что вы быстрее исчерпаете свой пул соединений.

Чтобы это произошло, вы, вероятно,не хотите, чтобы ваше свойство _db (которое, вероятно, должно быть переименовано в Db, или даже лучше DataContext, поскольку имена свойств в .Net обычно не начинаются с _), имеет защищенный установщик;подкласс может изменить значение свойства, и исходный контекст, который был там, был бы потерян без утилизации.

Что касается хранилища, то существует норма, что если у класса есть поле, которое является IDisposable,Вы должны также реализовать IDisposable в этом классе.В этом случае я бы, вероятно, изменил ваш IAsyncRepository<T>, чтобы он также требовал реализации IDisposable.Тогда ваша реализация хранилища должна располагать DbConext, а ваш контроллер вместо этого должен располагать экземпляром хранилища.Вероятно, в этом случае также было бы лучше, если бы контроллер не сохранял никаких ссылок на DbContext, а просто предоставлял вместо этого экземпляр репозитория.

Подробнее о том, как правильно реализовать IDisposable, можно прочитать здесь https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose?view=netframework-4.7.2

...