Подтвердить что ты не робот

Как вставить объект в класс валидатора WCF

После использования инъекции зависимостей для служб WCF существует ли способ использования DI для валидаторов WCF, чтобы можно было это сделать:

public class DIValidator : UserNamePasswordValidator
{
    private readonly IService service;

    [Inject]
    public DIValidator(IService service)
    {
        this.service = service;
    }

    public override void Validate(string userName, string password)
    {
        service.Login(userName, password);
    }
}

EDIT - я попытался применить совет Dzmitry к своему пользовательскому расширению поведения, поскольку мой валидатор определен в app.config. К сожалению, я получаю MethodMissingException, так как wcf хочет, чтобы мой валидатор имел конструктор по умолчанию:

System.MissingMethodException: No default constructor has been defined for this object.

at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)

Вот мой класс поведения:

    public class DependencyInjectionServiceBehavior : BehaviorExtensionElement, IServiceBehavior
    {
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            serviceHostBase.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = DISupport.Kernel.Get<IService>();
        }
    }
4b9b3361

Ответ 1

В общем пользовательский валидатор назначается программно (есть также возможность сделать это из файла конфигурации), что-то вроде этого, и оно выполняется непосредственно перед тем, как открывается хост-узел, и в основном это также время, когда вы создаете экземпляр контейнера DI, который будет далее использоваться для обслуживания экземпляров через поставщика экземпляров:

serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new LocalUserNamePasswordValidator();

Вы также можете использовать контейнер DI, чтобы создать свой собственный валидатор.

serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = unityContainer.Resolve<UserNamePasswordValidator>();

Ответ 2

Я знаю, что это не то решение, которое вы ищете, но я бы создал конструктор по умолчанию, который получит IService из вашего контейнера IoC (локатор сервисов вместо DI). Не самый приятный способ сделать это, но самое простое, о котором я могу думать.

Изменить: вы можете оставить конструктор, который позволяет вам вводить зависимость, если вам нужно высмеять IService для тестирования или любой другой purpouse.