Регистрация службы WCF в Unity Container

У меня есть библиотека службы wcf, которая размещена в службе Windows. Мне нужно перехватить вызовы методов службы. Для этого случая предлагается зарегистрировать WCF в контейнере Unity, как видно по этой ссылке.

http://weblogs.asp.net/fabio/archive/2009/03/24/inversion-of-control-with-wcf-and-unity.aspx

Я пытаюсь реализовать подобный подход сборкой Unity.WCF из Codeplex. Я не мог понять, куда поместить конфигурацию моего контейнера или загрузчик в библиотеку службы wcf (или службу windows). Твердый образец (против раствора) не предоставляется.

Мой Windows Service Host

    private UnityServiceHost _serviceHost = null;
    private readonly UnityContainer _container;


    public Service() {
        InitializeComponent();
        _container = new UnityContainer();
        _container.AddNewExtension<Interception>();
        _container.RegisterType<ISecurityRepository, SecurityRepository>();
        _container.Configure<Interception>().SetDefaultInterceptorFor<ISecurityRepository>(new TransparentProxyInterceptor());
    }

    protected override void OnStart(string[] args) {

        //SecurityService
        if (_serviceHost != null) {

            _serviceHost.Close();
        } else {
            _serviceHost = new UnityServiceHost(_container, typeof(SecurityRepository));
            _serviceHost.Open();
        }

    }

    protected override void OnStop() {

        //SecurityService
        if (_serviceHost != null) {

            _serviceHost.Close();
            _serviceHost = null;
        }
    }

Мой сервисный контракт

[ServiceContract(SessionMode = SessionMode.Required)]
public interface ISecurityRepository
{

    [OperationContract(IsInitiating = true)]
    IList<vNavigationTree> GetNavigationTree(string ticket);

    [OperationContract(IsInitiating = true)]
    string GetSessionGuid(string userName, string IP, string machineName);
}

В этом случае кажется, что перехватчик не работает. Вкратце, мне нужен пример проекта, в котором служба WCF зарегистрирована в контейнере DI, а методы службы перехвачены.

2 ответа

Решение

Я постараюсь объяснить, что я пытался сделать более подробно и как мне удалось это сделать. У меня есть приложение WPF, связывающееся с базой данных через WCF, что означает, что мое приложение разделено примерно на две части: на стороне клиента и на стороне сервера (WCF). Я завернул клиентскую часть в контейнер Unity через UnityBootStrapper, предоставленный PRISM. Мне нужно также обернуть серверную часть в другой контейнер Unity, чтобы Unity разрешала зависимости на стороне сервера.

Моя проблема решена с помощью Unity.WCF (доступного в виде пакета Nuget), который предоставляет класс UnityServiceHost, который можно использовать вместо ServiceHost. Я думаю, этот пакет создан так, как объясняет этот пост:

http://weblogs.asp.net/fabio/archive/2009/03/24/inversion-of-control-with-wcf-and-unity.aspx

Что вам нужно будет сделать, так это воспользоваться преимуществом конвейера перехвата единства.

Unity предоставляет встроенное поведение внедрения политик для облегчения реализации aop. Поведение внедрения политики добавляет или внедряет некоторые функции в конкретные методы, используя обработчики вызовов и правила сопоставления для каждого метода.

а. Начните с пользовательского интерфейса ICallhandler.

>>    public interface ILogAttributeHandler : ICallHandler
>>    {
>>    }
>>

б. Добавьте свою реализацию для вашего обработчика. Это совет, который вы хотите применить, когда ваш метод перехвачен.

>>    public class ActivityAttributeHandler : ILogAttributeHandler
>>    {
>>    public ActivityAttributeHandler(string activityType)
>>    {
>>    ActivityType = activityType;
>>    }

>>    private string ActivityType { get; set; }
>>    public int Order { get; set; }

>>    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
>>    {
 >>           //// Invoke the handler
>>            IMethodReturn output = getNext()(input, getNext);

>>            //// Perform post-processing task
>>            var agent = output.ReturnValue as Agent;

>>            if (agent != null)
>>            {
>>               //// do work here 
>>            }

>>            return getNext()(input, getNext);
>>        }
}

с. Создайте свой пользовательский атрибут, он будет использоваться как pointcut в программе.

>>  [AttributeUsage(AttributeTargets.Method)]
>>   public class ActivityAttribute : HandlerAttribute
>>    {
>>        private readonly string _activityName;

 >>       public ActivityAttribute(string activityName)
>>        {
>>            _activityName = activityName;
>>        }
>> }
>>       public override ICallHandler CreateHandler(IUnityContainer container)
>>      {
>>  return null;
>>}

д. Теперь все, что у вас осталось, это настроить перехват в вашей конфигурации Unity и добавить атрибут к вашему интерфейсу сервиса, который вы хотите перехватить.

>  container
>                 .RegisterType<ILogAttributeHandler, LogAttributeHandler>()
>                 .AddNewExtension<Interception>()
>                 .Configure<Interception>()
>                .SetInterceptorFor<ISecurityRepository>("SecurityRepository", new
> InterfaceInterceptor());

е. Применить атрибуты к операциям вашего интерфейса

>>public interface ISecurityRepository 
>> {
>>    [OperationContract(IsInitiating = true)]
>>    [Activity("Logon")]
>>    IList<vNavigationTree> GetNavigationTree(string ticket)
>>}
Другие вопросы по тегам