4

ジェネリックスとCastleWCF機能を使用して、大きなプロジェクトのWCFCRUD部分のコードの記述を最小限に抑えようとしました。

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コントローラー(dtosおよびサービスのすべての基本的なクラッドに1つのコントローラー

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

クライアント側で、WCFクライアントをWindsorコンテナに登録します

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

Everythigは正常に動作しており、コンポーネントとサービスが登録され、コントローラーが適切に作成され、サービスが提供されています

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

ICrudService <>にServiceContract属性を配置し、そこのメソッドにOperationContractを追加して、IResourceServiceからGet()の重複する宣言を削除する必要があると思います。

于 2012-11-21T05:58:46.150 に答える