【问题标题】:Castle WCF Facility, Use of generic interface for non generic contractCastle WCF Facility,对非通用合同使用通用接口
【发布时间】:2012-11-20 13:29:05
【问题描述】:

我试图通过使用泛型和城堡 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 个控制器,用于 dto 和服务的所有基本 crud

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

在客户端,我在Windsor Container 中注册 WCF 客户端

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

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

readonly ICRUDService<T> service;

in 控制器的类型是

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(...

如何让它发挥作用?

【问题讨论】:

    标签: wcf inversion-of-control castle-windsor wcffacility


    【解决方案1】:

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

    [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 没有任何问题。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-18
        相关资源
        最近更新 更多