2017-02-05 6 views
6

私はIoCをIocSingletonAttributeを持つクラスを自動的に登録する機能を持つdelphiでIoCを作成しました。Delphi IoCの作成。 Delphiのリンカが未使用のクラスを削除しないようにする方法

自動登録は次のようになります。

procedure TIocContainer.AutoRegister; 
var 
    ctx: TRttiContext; 
    rType: TRttiType; 
    attr: TCustomAttribute; 
    &Type: PTypeInfo; 
begin 
    ctx := TRttiContext.Create; 
    for rType in ctx.GetTypes do 
    Begin 
    for attr in rType.GetAttributes do 
    Begin 
     if TypeInfo(IocSingletonAttribute) = attr.ClassInfo then 
     Begin 
     &Type := IocSingletonAttribute(attr).&Type; 
     RegisterType(&Type, rType.Handle, True); 
     End; 
    End; 
    End; 
end; 

次に、実装を作成してIocSingletonAttributeを追加します。これは次のようになります

[IocSingleton(TypeInfo(IIocSingleton))] 
TIocSingleton = class(TInterfacedObject, IIocSingleton) 
    procedure DoSomeWork; 
end; 

これでプログラムの実際のコードになりました。私が以下のコードを書くと、IoCは動作しません。 AutoRegisterプロシージャはTIocSingletonを取得しませんでした。

var 
    Ioc: TIocContainer; 
    Singleton: IIocSingleton; 
begin 
    Ioc := TIocContainer.Create; 
    try  
    Ioc.AutoRegister; 
    Singleton := Ioc.Resolve<IIocSingleton>(); 
    Singleton.DoSomeWork; 
    finally 
    Ioc.Free; 
    end; 
end. 

しかし、以下のコードを書き換えても、すべてが期待通りに機能します。 TIocSingletonクラスをどのように宣言して使用したかに注目してください。

var 
    Ioc: TIocContainer; 
    Singleton: IIocSingleton; 
    ASingleton: TIocSingleton; 
begin 
    Ioc := TIocContainer.Create; 
    ASingleton := TIocSingleton.Create; 
    try  
    Ioc.AutoRegister; 
    Singleton := Ioc.Resolve<IIocSingleton>(); 
    Singleton.DoSomeWork; 
    finally 
    Singleton.Free; 
    Ioc.Free; 
    end; 
end. 

だから、これに基づいて、私はそれが明示的にアプリケーションのどの部分に使用されていませんでしたので、Delphiのコンパイラ、リンカは、最初の例ではTIocSingletonを取り除いていると仮定しています。だから私の質問は、コンパイラの '特定のクラスのための未使用のコードを削除する機能を有効にすることは可能ですか?または、私の問題がリンカーではない場合、誰かが最初の例ではなく2番目の例がうまくいく理由を明らかにすることができますか?

+3

私はあなたの唯一の希望は、リンカーがクラスを含むように強制するいくつかのコードを含めることだと思います。 TIoCSingleton.ClassNameの初期化を追加します。はい、あなたが登録するかもしれないすべてのクラスのためにそれをしなければなりません。もう一つの可能​​性は、パッケージを使用している可能性があります –

+0

チップのおかげで。ユニットの初期化部分の下でTIoCSingleton.ClassNameを呼び出すことはあまりにも悪くないかもしれません – Coolio

答えて

1

Sebastian ZがAgustin Ortuのコメントに感謝します。どちらの回答も私を最終的な解決に導いてくれました。残念ながら、1つのクラスに対してSTRONGLINKTYPESを使用することはできません。クラスを何らかの方法で参照する必要があります。私はAugstin Ortuの正確な提案を使わないことに決めましたが、私はそのコンセプトを使っていました。

IoCが定義されているユニットでは、次の空の手順が出力されます。

procedure IocReference(AClass: TClass); 

implementation 

procedure IocReference(AClass: TClass); 
begin 
end; 

そして、IOCが使用するクラスを作成し、クラスで私は、次の

initialization 
    IocReference(TIocSingleton); 
end. 

コードを削除するだけではなく呼び出しからリンカを維持するための手順を使用する理由を追加例えば、(TIocSingleton.ClassName)はより良い情報を提供するということです。別のプログラマーがコードを読んでいると、なぜその行があるのか​​をよく知ることができます。

3

{$STRONGLINKTYPES ON}ディレクティブを.dprに追加します。次に、これらのタイプを含める必要があります。しかし、1つのクラスでは利用できないため、アプリケーションが確実に爆発します。

+0

これは正常に動作しますか?ほとんどのコンパイラー・ディレクティブは、コンパイラー・オプション( - > .dprojファイル)または個別のユニットに追加して効果を持たせる必要があります。 – dummzeuch

+0

私は訂正されました:「確実に動作するためには、ディレクティブはメインプログラムまたはライブラリソース(.dpr)になければなりません。 "http://docwiki.embarcadero.com/RADStudio/en/Strong_link_types_(Delphi) – dummzeuch

関連する問題