Как следует кодировать Dispose в классах, реализующих IDependencyResolver и IDependencyScope?

StackOverflow https://stackoverflow.com//questions/21009235

Вопрос

Я запустил анализ кода в своем проекте веб-API, в котором пытаюсь реализовать IoC и DI с помощью Castle Windsor, и обнаружил четыре проблемы.Все четыре вещи, которые он нашел, были в WindsorDependencyResolver, и все четыре являются «правильной реализацией IDisposable», а именно:

0) CA1063 Реализуйте Idisposable правильно обеспечивает переоценку реализации Dispose (Bool) на «WindSordEpendencyResolver» или отметьте тип как герметичный.Вызов Dispose(false) должен очищать только собственные ресурсы.Вызов Dispose(true) должен очистить как управляемые, так и собственные ресурсы.

Это указывает на эту строку кода:

public class WindsorDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver

1) CA1063 Реализуйте Idisposable правильно изменить 'windsordependencyresolver.dispose ()', чтобы он вызовал (true (true), затем вызывает Gc.suppressfinalize на текущем экземпляре объекта («это» или «я» в Visual Basic), а затем возвращается.

Это указывает на эту строку кода:

public void Dispose()

2) То же, что и O, но для WindsorDependencyScope:Класс IDependencyScope.

3) То же, что 1, но ""

Я получил код, который пытаюсь использовать, из онлайн-статей о замке Виндзор, в основном из эта почта.Полный код этого файла:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Dependencies;
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using System.Web.Http;
using Castle.MicroKernel.Lifestyle;
using Castle.MicroKernel.SubSystems.Configuration;
using HandheldServer.Models;

namespace HandheldServer
{
    public class WindsorDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
    {
        private readonly IWindsorContainer _container;

        public WindsorDependencyResolver(IWindsorContainer container)
        {
            _container = container;
        }

        public IDependencyScope BeginScope()
        {
            return new WindsorDependencyScope(_container);
        }

        public object GetService(Type serviceType)
        {
            return _container.Kernel.HasComponent(serviceType) ? _container.Resolve(serviceType) : null;
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (!_container.Kernel.HasComponent(serviceType))
            {
                return new object[0];
            }

            return _container.ResolveAll(serviceType).Cast<object>();
        }

        public void Dispose()
        {
            _container.Dispose();
        }
    }

    public class WindsorDependencyScope : IDependencyScope
    {
        private readonly IWindsorContainer _container;
        private readonly IDisposable _scope;

        public WindsorDependencyScope(IWindsorContainer container)
        {
            this._container = container;
            this._scope = container.BeginScope(); 
        }

        public object GetService(Type serviceType)
        {
            if (_container.Kernel.HasComponent(serviceType))
            {
                return _container.Resolve(serviceType);
            }
            else
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return this._container.ResolveAll(serviceType).Cast<object>();
        }

        public void Dispose()
        {
            this._scope.Dispose();
        }
    }

    public class ApiControllersInstaller : IWindsorInstaller
    {
        public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
        {
            container.Register(Classes.FromThisAssembly() // should it be Types instead of Classes?
             .BasedOn<ApiController>()
             .LifestylePerWebRequest());
        }
    }

    // This idea from https://github.com/argeset/set-locale/blob/master/src/client/SetLocale.Client.Web/Configurations/IocConfig.cs
    public class ServiceInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
                Component.For<IDeliveryItemRepository>().ImplementedBy<DeliveryItemRepository>().LifestylePerWebRequest(),
                Component.For<IDeliveryRepository>().ImplementedBy<DeliveryRepository>().LifestylePerWebRequest(),
                Component.For<IDepartmentRepository>().ImplementedBy<DepartmentRepository>().LifestylePerWebRequest(),
                Component.For<IExpenseRepository>().ImplementedBy<ExpenseRepository>().LifestylePerWebRequest(),
                Component.For<IInventoryItemRepository>().ImplementedBy<InventoryItemRepository>().LifestylePerWebRequest(),
                Component.For<IInventoryRepository>().ImplementedBy<InventoryRepository>().LifestylePerWebRequest(),
                Component.For<IItemGroupRepository>().ImplementedBy<ItemGroupRepository>().LifestylePerWebRequest());
        }
    }
}

Как лучше всего смягчить инструмент анализа кода?

Это было полезно?

Решение

Прежде чем ответить на ваш вопрос, обратите внимание, что вам следует быть очень осторожными, звоня Dispose() на объекте, который вы не создавали и поэтому, вероятно, не несете ответственности.Я имею в виду линию

_container.Dispose();

тот container был передан настолько, строго говоря, что вы не можете его выбросить.

Самый простой способ смягчить инструмент анализа кода — реализовать IDisposable как рекомендовано

public class WindsorDependencyResolver
{
    public WindsorDependencyResolver()
    {
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private bool disposed;

    protected virtual void Dispose(bool disposing)
    {
        if (this.disposed) return;

        if (disposing)
        {
            // call dispose on managed resources
            // set to null
        }

        this.disposed = true;
    }
}

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top