3

質問にあまり関係のない理由で、TRemotableクラスでジェネリックを使用したいと思います。Soap.OPToSOAPDomConv.pasにはこれに関していくつかの問題があることがわかりました。ジェネリックスを処理できないと思われる古いRTTIを使用しているため、クラスはxmlにシリアル化されません。

Soap.OPToSOAPDomConv.pasを変更して、ジェネリックで動作するようにしました。私の主な質問は、Delphiソースファイルに変更を加えても大丈夫だと考えられるかどうかです。そうでない場合、これを行うためのより良い方法はありますか?私だけが使っている限り、大きな問題はないと思いますが、ソースを他の人に配布するのは難しいですし、Delphiにも将来の変更を検討する必要があります。この長い投稿の残りの部分は、私が実際に行っていることの詳細です:-)

Soap.OPToSOAPDomConv.pas(行3759)でこれを変更しました

if SerializeProps then
begin
  { Serialized published properties }
  Count := GetTypeData(Instance.ClassInfo)^.PropCount;
  if Count > 0 then
  begin
    CheckedElemURI := False;
    GetMem(PropList, Count * SizeOf(Pointer));
    try
      GetPropInfos(Instance.ClassInfo, PropList);

宛先:(私が推測する最も美しい実装ではありません)

手順の新しい変数:

Context: TRttiContext;       
RttiProperty:  TRttiProperty;

行3759:

if SerializeProps then
begin
  { Serialized published properties }
  Count := 0;
  for RttiProperty in Context.GetType(Instance.ClassInfo).GetProperties do
  begin
    if RttiProperty.Visibility = mvPublished then //The old method only read published
      Count := Count + 1;                         //RTTI scoping [mvPublished] requires changes to
  end;                                            //soap.InvRegistry
  begin
    CheckedElemURI := False;
    GetMem(PropList, Count * SizeOf(Pointer));
    try
      I := 0;
      for RttiProperty in Context.GetType(Instance.ClassInfo).GetProperties do
        if RttiProperty.Visibility = mvPublished then
        begin
          PropList[I] := TRttiInstanceProperty(RttiProperty).PropInfo;
          I := I + 1;
        end;

私がしていることに関するいくつかの詳細はおそらく役に立ちます。背景には、SOAP Webサービスからインポートされたwsdlが、約2000のクラスと300k行のコードで構成される巨大なユニットを生成することがあります。Webサービスの設計は私の手に負えません。WSDLインポーターは、これらすべてのクラスをRTTIで表示できるようにします。これにより、RTTIスペースが消費され、ユニットはコンパイルされません。

私はあちこちでコードをリファクタリングし、現在は機能する実装があります。リファクタリング中に、ジェネリックスを使用することで、約50000行の冗長コードを切り取ることができることがわかりました。Delphiはインポートされたwsdlを「現状のまま」コンパイルしないため、Webサービスで新しいメソッドが利用可能になるたびにユニットを手動で保守する必要があるため、できるだけ読みやすくしたいと思います。

基本的には以下のように変更しています。サンプルには非常に単純化されたクラスがあり、サンプルには実際にはリファクタリングされたコードの行数が多くなっていますが、元のクラスに多くのプロシージャなどがあることを考慮すると、このメソッドはユニットを非常に読みやすくし、クラスの作成も簡単になります。

TLCar = class(TRemotable)
private
  FEngine: string;
  FName: string;
published
  property Name: string read FName write FName;
  property Engine: string read FEngine write FEngine;
end;

TLBicycle = class(TRemotable)
private
  FPedals: string;
  FName: string;
published
  property Name: string read FName write FName;
  property Pedals: string read FPedals write FPedals;
end;

TListCarRequest = class(TRemotable)
private
  FreturnedTags: TLCar;
published
  property returnedTags: TLCar read FreturnedTags write FreturnedTags;
end;

TListBiCycleRequest = class(TRemotable)
private
  FreturnedTags: TLBicycle;
published
  property returnedTags: TLBicycle read FreturnedTags write FreturnedTags;

に:

TCommonReturnedTags = class(TRemotable)
private
  FName: string;
published
  property Name: string read FName write FName;
end;

TLCar = class(TCommonReturnedTags)
private
  FEngine: string;
published
  property Engine: string read FEngine write FEngine;
end;

TLBicycle = class(TCommonReturnedTags)
private
  FPedals: string;
published
  property Pedals: string read FPedals write FPedals;
end;

TGenericListRequest<T: TCommonReturnedTags, constructor> = class(TRemotable)
private
  FreturnedTags: T;
published
  property returnedTags: T read FreturnedTags write FreturnedTags;
end;

TListCarRequest = class(TGenericListRequest<TLCar>)
end;

TListBiCycleRequest = class(TGenericListRequest<TLBicycle>)
end;

敬具、

ダン

4

1 に答える 1

1

このような変更を行う場合、考慮すべき点が 2 つあります。まず第一に、変更は既存の機能に影響を与える可能性があります。この場合のように、機能がこの操作にとって新しいため安全であると言えます。そのため、予期しない動作は発生しないはずです。2 番目の部分は、evolution 開発環境です。環境の進化に伴う問題は、行動間の結合が変化する可能性があり、それが予期せぬ事態につながる可能性があることです. 現時点では、XE2 に更新のシェアがあると想定しても問題ありません。そうでない場合は、パッチを適用したり更新したりするときに注意する必要があります。XE2 から XE3 への変更のような 2 番目の種類の変更は、より適切に処理できます。以下をSoap.OPToSOAPDomConv.pasの先頭に置くだけです:

{$IFNDEF VER230}
   {$MESSAGE ERROR 'Intended to be used with XE2'}
{$ENDIF}

コンパイル中にエラーが発生すると、そのファイルに何かがあったことを漠然と思い出すかもしれません. うまくいけば、これがあなたが知りたかったことでした。

于 2014-03-06T20:14:39.920 に答える