Castle Windsor:将WCF客户端与本地组件混合使用

时间:2014-07-17 11:03:55

标签: castle-windsor castle-dynamicproxy windsor-3.0 windsor-facilities

我有服务(在Castle Windsor意义上),这些服务标有[ServiceContract]属性。 其中一些是WCF托管,另一些是本地运行。

我希望我的安装程序尽可能通用。 我正在寻找的逻辑是:

  1. 在应用程序的bin目录中查找服务。
  2. 您找到的任何实现,在本地使用(这也必须与装饰器一起使用)。
  3. 您找不到的任何内容,假设应通过WCF调用。
  4. 服务托管在Web应用程序中,Application_Start方法设置所有内容并通过WCF托管服务。在这个Web应用程序中,通过WCF访问其他服务也没有任何进一步的逻辑。

    但是,我也有一个ASP.NET MVC应用程序,我无法通过WCF调用服务。 我总是得到一条错误消息,上面写着:

      

    类型IMyService是抽象的。   因此,无法将其实例化为服务IMyService的实现

    而且,当我注册一个拦截器时,它说

      

    这是一个DynamicProxy2错误:拦截器试图“继续”'方法' MyDataContract FooMethod(System.String)'没有目标。在没有目标的情况下调用方法时,没有实现'继续' to和拦截器的责任是模仿实现(设置返回值,输出参数等)

    这是我最近的尝试(换句话说,它是" 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);
        }
    

    我当然也想摆脱预处理器指令。 系统应自动检测装饰器是否存在。 &#34;本地&#34;实现在名为 .Impl.dll的程序集中,装饰器在程序集中,名为* .ServiceProxy。*。dll。

    哦,如果我删除非本地服务的特殊处理(那些将通过WCF调用的服务)我总是得到错误消息&#34;客户端模型需要和端点。&#34;

    非常感谢任何帮助。

0 个答案:

没有答案