2017-02-05 52 views
6

Tôi đã tạo ra một IoC trong delphi với khả năng tự động đăng ký bất kỳ lớp học có một IocSingletonAttribute cho nó.Tạo IoC Delphi. Làm thế nào để vô hiệu hóa liên kết Delphi của từ loại bỏ các lớp không sử dụng

AutoRegister trông giống như sau.

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; 

Sau đó, tôi tạo triển khai và thêm thuộc tính IocSingletonAttribute vào nó. Có vẻ như đây là

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

Vì vậy, bây giờ đến mã thực tế của chương trình. Nếu tôi viết mã dưới IoC không hoạt động. Thủ tục AutoRegister đã không nhận TIocSingleton.

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

Nhưng nếu tôi viết mã bên dưới thay vào đó mọi thứ hoạt động như mong đợi. Chú ý cách tôi đã khai báo lớp TIocSingleton và đã sử dụng nó như thế nào.

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. 

Vì vậy, trên cơ sở này, tôi giả Delphi của trình biên dịch liên kết là loại bỏ TIocSingleton trong ví dụ đầu tiên bởi vì nó không bao giờ được sử dụng một cách rõ ràng trong bất kỳ phần nào của ứng dụng. Vì vậy, câu hỏi của tôi là, có thể bật tính năng 'gỡ bỏ mã không sử dụng' của trình biên dịch cho một lớp nhất định không? Hoặc nếu vấn đề của tôi không phải là mối liên kết, bất cứ ai có thể làm sáng tỏ lý do tại sao ví dụ thứ hai hoạt động chứ không phải là ví dụ đầu tiên?

+3

Tôi nghĩ rằng hy vọng duy nhất của bạn là bao gồm một số mã buộc trình liên kết đưa vào lớp học. Việc thêm khởi tạo TIoCSingleton.ClassName sẽ thực hiện. Có, bạn phải làm điều đó cho mọi lớp học bạn có thể đăng ký. Một khả năng khác có thể đang sử dụng các gói –

+0

Cảm ơn bạn đã tìm mẹo. Gọi TIoCSingleton.ClassName dưới phần khởi tạo của đơn vị có thể không quá tệ để sống với – Coolio

Trả lời

1

Nhờ Sebastian Z trả lời và cho nhận xét của Agustin Ortu. Cả hai câu trả lời của họ đã đưa tôi đến một giải pháp cuối cùng. Không thể sử dụng STRONGLINKTYPES chỉ cho một lớp, thật không may và lớp học cần được tham chiếu bằng cách nào đó. Tôi quyết định không sử dụng đề xuất chính xác của Augstin Ortu nhưng tôi đã sử dụng khái niệm này.

Trong đơn vị nơi IoC được xác định, tôi xuất quy trình trống sau đây.

procedure IocReference(AClass: TClass); 

implementation 

procedure IocReference(AClass: TClass); 
begin 
end; 

Và trong lớp mà tạo ra một lớp học để được sử dụng bởi IoC tôi thêm những điều sau

initialization 
    IocReference(TIocSingleton); 
end. 

Lý do để sử dụng một thủ tục để giữ mối liên kết từ bỏ các mã thay vì chỉ gọi một chức năng lớp, ví dụ (TIocSingleton.ClassName) là nó cung cấp thông tin tốt hơn. Nếu một lập trình viên khác đọc mã, họ có thể đoán đúng là tại sao dòng đó lại có.

3

Thêm chỉ thị {$STRONGLINKTYPES ON} vào .dpr. Sau đó, những loại đó nên được bao gồm. Nhưng nó chắc chắn sẽ làm nổ tung ứng dụng của bạn, vì nó không có sẵn cho một lớp duy nhất.

+0

Bạn có chắc chắn điều này sẽ hoạt động không? Hầu hết các chỉ thị của trình biên dịch phải được thêm vào các tùy chọn trình biên dịch (-> .dproj) hoặc cho các đơn vị riêng lẻ có bất kỳ hiệu ứng nào. – dummzeuch

+0

Tôi đã sửa chữa: "Để hoạt động đáng tin cậy, chỉ thị phải nằm trong chương trình chính hoặc nguồn thư viện (.dpr)." "http://docwiki.embarcadero.com/RADStudio/en/Strong_link_types_(Delphi) – dummzeuch

Các vấn đề liên quan