Castle Windsor: смешивание клиентов WCF с локальными компонентами

У меня есть службы (в смысле Виндзорского замка), которые помечены атрибутом [ServiceContract]. Некоторые из них размещены на WCF, другие работают локально.

Я хочу, чтобы мой установщик был настолько общим, насколько это возможно. Логика, которую я ищу, заключается в следующем:

  1. Ищите сервисы в каталоге bin приложения.
  2. Все, что вы нашли реализацию, используйте локально (это также должно работать с декораторами).
  3. Все, что вы не нашли, предположим, что будет вызвано через WCF.

Службы размещаются в веб-приложении, метод Application_Start все настраивает и размещает службы через WCF. В этом веб-приложении доступ к другим службам через WCF также работает без какой-либо дополнительной логики.

Однако у меня также есть приложение ASP.NET MVC, и я не могу заставить его вызывать сервисы через WCF. Я всегда получаю сообщение об ошибке:

Тип IMyService является абстрактным. Таким образом, его невозможно реализовать как реализацию службы IMyService.

И когда я регистрирую перехватчик, он говорит

Это ошибка DynamicProxy2: перехватчик попытался "продолжить" для метода "MyDataContract FooMethod(System.String)", который не имеет цели. При вызове метода без цели не существует реализации, к которой следует "переходить", и перехватчик обязан имитировать реализацию (установить возвращаемое значение, аргументы out и т. Д.)

Вот моя последняя попытка (другими словами, это часть "ConfigureAsWcfClient", которая не работает):

    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Classes.FromAssemblyInDirectory(Constants.MyAssemblyFilter)
                   .Where(ImplementsServiceContract)
                   .WithServiceSelect((x, y) => GetServices(x))

#if DECORATORS_PRESENT
                   .ConfigureIf(IsDecorator, c => c
                       .IsDefault(y => IsDecorating(c, y))
                       .Named(GetNameOfServiceContract(c)))
#else
            // TODO: FIXME: Set name for services without decorator
                   .ConfigureIf(c => string.IsNullOrEmpty(c.Name),
                                c => c.Named(GetNameOfServiceContract(c)))
#endif
            );

        container.Register(Types.FromAssemblyInDirectory(Constants.BikubeAssemblyFilter)
                .Where(x => IsServiceContract(x) && !container.Kernel.HasComponent(x))
                .WithServiceSelf()
                .Configure(ConfigureAsWcfClient));
    }

    private static void ConfigureAsWcfClient(ComponentRegistration c)
    {
        c.Named(c.Implementation.Name).AsWcfClient(WcfEndpoint.FromConfiguration("*"));
    }

    private static string GetNameOfServiceContract(ComponentRegistration c)
    {
        var name = GetServices(c.Implementation).First().FullName;
        Debug.WriteLine("CW register sevice contract: " + name);
        return name;
    }

    private static bool ImplementsServiceContract(Type type)
    {
        return GetServices(type).Any();
    }

    private static IEnumerable<Type> GetServices(Type type)
    {
        return type.GetInterfaces().Where(IsServiceContract);
    }

    private static bool IsServiceContract(Type type)
    {
        var ns = type.Namespace;
        return ns != null && ns.StartsWith(Constants.NamespacePrefix) && Attribute.IsDefined(type, typeof(ServiceContractAttribute));
    }

    private static bool IsDecorator(ComponentRegistration c)
    {
        Type component = c.Implementation;
        var isDecorator = GetServices(component).Any(x => IsDecorating(c, x));
        return isDecorator;
    }

    private static bool IsDecorating(ComponentRegistration c, Type service)
    {
        Type component = c.Implementation;
        return !component.Assembly.GetName().Name.EndsWith(".Impl", StringComparison.InvariantCultureIgnoreCase);
    }

Я, конечно, также хотел бы избавиться от директивы препроцессора. Система должна автоматически определять наличие декораторов. "Локальные" реализации находятся в сборках с именем .Impl.dll, декораторы - в сборках, которые называются *.ServiceProxy. *. Dll.

Да, и если я уберу специальную обработку нелокальных сервисов (тех, которые должны вызываться через WCF), я всегда получаю сообщение об ошибке "Требуется модель клиента и конечная точка".

Любая помощь высоко ценится.

0 ответов

Другие вопросы по тегам