0

我有标有 [ServiceContract] 属性的服务(在温莎城堡的意义上)。其中一些是 WCF 托管的,另一些是在本地运行的。

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

  1. 在应用程序的 bin 目录中查找服务。
  2. 您找到实现的任何东西,都可以在本地使用(这也必须与装饰器一起使用)。
  3. 任何你没有找到的东西,假设应该通过 WCF 调用。

服务托管在 Web 应用程序中,Application_Start 方法设置所有内容并通过 WCF 托管服务。在此 Web 应用程序中,通过 WCF 访问其他服务也可以正常工作,无需任何进一步的逻辑。

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

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

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

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

这是我最近的尝试(换句话说,它是“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 调用的服务)的特殊处理,我总是会收到错误消息“客户端模型需要和端点”。

非常感谢任何帮助。

4

0 回答 0