2015-12-09 2 views
4

Я использую RemObjects DataAbstract вместе с Spring4d. RemObjects создает файл SchemaServer_Intf.pas, содержащий интерфейсы для всех типов таблиц, которые существуют в его схеме. Это позволяет «строго типизированных» наборов данных, что позволяет один получить доступ к полю, используяSpring4d: Как «заставить» контейнер верить, что класс реализует интерфейс

(aDataSet as IMyDataSet).MyField := aValue 

Вот снимок одного из интерфейсов, порожденных DataAbstract

IEntiteType = interface(IDAStronglyTypedDataTable) 
    ['{96B82FF7-D087-403C-821A-0323034B4B99}'] 
    { Property getters and setters } 
    function GetEntiteIdValue: String; 
    procedure SetEntiteIdValue(const aValue: String); 
    function GetEntiteIdIsNull: Boolean; 
    procedure SetEntiteIdIsNull(const aValue: Boolean); 
    function GetNameValue: WideString; 
    procedure SetNameValue(const aValue: WideString); 
    function GetNameIsNull: Boolean; 
    procedure SetNameIsNull(const aValue: Boolean); 
    function GetIsSystemValue: SmallInt; 
    procedure SetIsSystemValue(const aValue: SmallInt); 
    function GetIsSystemIsNull: Boolean; 
    procedure SetIsSystemIsNull(const aValue: Boolean); 


    { Properties } 
    property EntiteId: String read GetEntiteIdValue write SetEntiteIdValue; 
    property EntiteIdIsNull: Boolean read GetEntiteIdIsNull write SetEntiteIdIsNull; 
    property Name: WideString read GetNameValue write SetNameValue; 
    property NameIsNull: Boolean read GetNameIsNull write SetNameIsNull; 
    property IsSystem: SmallInt read GetIsSystemValue write SetIsSystemValue; 
    property IsSystemIsNull: Boolean read GetIsSystemIsNull write SetIsSystemIsNull; 
    end; 

Хотя, есть одна проблема. Если вы разыгрываете DataTable так:

aDataTable := IEntiteType(TDAMemDataTable.Create(nil)); 

Вы будете иметь «интерфейс не поддерживается ошибка»

Но, как только вы делаете:

aDataTable.LogicalName := 'EntiteType'; 
aDataTable.BusinessRulesId := MyBusinessRuleID; 

Вы можете безопасно напишите

aDataTable := IEntiteType(TDAMemDataTable.Create(nil)); 

И вы не получите никаких ошибок.

Так, с Spring4d, я думал о написании этого в моей регистрации блока:

aContainer.RegisterType<TDAMemDataTable>.Implements<IEntiteType>.DelegateTo(
    function : TDAMemDataTable 
    var aDataTable : TDAMemDataTable; 
    begin 
     Result:= TDAMemDataTable.Create(nil); 
     Result.LogicalName := 'EntiteType'; 
     Result.BusinessRulesId := MyBusinessRuleId;   
    end 
) 

Но тогда, Spring4d броски (с рассудком) Ошибка:

Exception 'first chance' à $762D5B68. Classe d'exception ERegistrationException avec un message 'Component type "uDAMemDataTable.TDAMemDataTable" incompatible with service type "SchemaClient_Intf.IEntiteType".'. Processus EntiteREM2.exe (3088) 

Есть ли способ, чтобы переопределить эта проверка?

ответ

4

Хорошо, я нашел способ сделать это. Супер просто на самом деле:

aContainer.RegisterType<IAddress>.DelegateTo(
    function : IAddress 
    var aTable : TDAMemDataTable; 
    begin 
     aTable := TDAMemDataTable.Create(nil); 
     aTable.LogicalName := nme_Address; 
     aTable.BusinessRulesID := RID_Address; 
     Result := aTable as IAddress; 
    end 
); 

Кроме того, для людей, заинтересованных в регистрации много таблиц в элегантной моды:

aContainer.RegisterType<IAddress>.DelegateTo(TableConfigurator.GetTableDelegate<IAddress>(nme_Address, RID_Address)); 
// Registering other tables here... 

Просто создать некоторый класс "Helper" с помощью этого метода:

class function TableConfigurator.GetTableDelegate<T>(aLogicalName, aBusinessRulesId: string): TActivatorDelegate<T>; 
begin 
    Result := (function: T 
    var 
     aTable: TDAMemDataTable; 
    begin 
     aTable := TDAMemDataTable.Create(nil); 
     aTable.LogicalName := aLogicalName; 
     aTable.BusinessRulesID := aBusinessRulesId; 
     Result := T(TValue.From(aTable).AsInterface); 
    end); 
end; 

 Смежные вопросы

  • Нет связанных вопросов^_^