4

我试图通过使用泛型和城堡 WCF 设施来尽量减少大型项目的 WCF CRUD 部分的代码编写。

我有 WCF 服务合同:

[ServiceContract]
public interface IResourceService : ICRUDService<DTOResource>
{
    [OperationContract]
    DTOResource Get(long id);
}

generic界面

public interface ICRUDService<T> where T is IDTO
{
    T Get(long id);
}

也是通用MVC控制器(1 个控制器用于 dtos 和服务的所有基本 crud

public class CRUDController<T> : Controller where T is IDTO
{
    readonly ICRUDService<T> service;
    public CRUDController(ICRUDService<T> service)
    {
        this.service = service;
    }   
}

在客户端,我在Windsor容器中注册 WCF 客户端

Component
  .For<IResourceService , ICRUDService<DTOResource>>()
  .AsWcfClient(... standard stuff... )

一切正常,组件和服务注册,控制器创建正确,服务

readonly ICRUDService<T> service;

在控制器中是类型

Castle.Proxies.IResourceService 

但是当我尝试在控制器中使用服务时出现错误

Method Get is not supported on this proxy, this can happen if the method is
 not marked with OperationContractAttribute or if the interface type is not 
 marked with ServiceContractAttribute.

当在控制器中时,我硬编码转换

((IResourceService)service).Get(id);

一切运行正常,所以我相信这个问题是可以解决的。

我也尝试过使用 Forward (结果相同):

Component
  .For<IActionTypeService>
  .Forward<ICRUDService<DTOResource>>().AsWcfClient(...

如何让它发挥作用?

4

2 回答 2

2

最后我不得不在客户端使用“通道工厂”。我能够WCF Facility在服务器端使用 Windsor 来注册通用合同:

[ServiceContract]
public interface ICRUDService<I>
{
    [OperationContract]
    I Get(int id);
}

具有通用实现

public class CRUDService<I, IEntity> : ServiceBase, ICRUDService<I>
{
    public I Get(int id)
    {            
        ...
    }

以标准方式(适用于多种类型)

private void InstallExample<I, IEntity>(IWindsorContainer container)
{
container.Register(
    Component
        .For<ICRUDService<I>>()
        .ImplementedBy(CRUDService<I, IEntity>)
        .Named("somename")
        .AsWcfService(
            new DefaultServiceModel()
                .Hosted()
                .PublishMetadata(x => x.EnableHttpGet())
                .AddEndpoints(WcfEndpoint
                .BoundTo(new BasicHttpBinding())
                .At("someAddress")
            )
        )
        .LifeStyle.PerWcfOperation();
}

无文件激活web.config

<add factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" service="ClientService" relativeAddress="./ClientService.svc" />

在服务器端它工作得很好。可悲的是,在客户端我没有找到 WCFFacility 的工作解决方案,我不得不使用ChannelFactory(它工作得很好)

ChannelFactory<ICRUDService<I>> factory = new ChannelFactory<ICRUDService<I>>(someBinding, someEndpoint);

其余的(我正在使用的标准非通用服务WCF Facility没有任何问题。

于 2013-02-28T12:02:46.880 回答
1

我认为您需要将 ServiceContract 属性放在 ICrudService<> 上,将 OperationContract 添加到那里的方法中,并从 IResourceService 中删除 Get() 的重复声明。

于 2012-11-21T05:58:46.150 回答