2012-03-31 9 views
8

Có thể đăng ký một lớp học với thông số dự kiến ​​được chuyển từ điểm sáng tạo?delphi - làm thế nào để vượt qua một tham số từ instantiator đến một constructor trong framework phun phụ thuộc spring4d?

Tôi biết nó có thể được thực hiện một cái gì đó như thế này:

GlobalContainer.RegisterType<TUserProcessor>.Implements<IUserUpgrader>. 
AsTransient.DelegateTo(
    function: TUserProcessor 
    begin 
     Result := TUserProcessor.Create(GetCurrentUser); 
    end 
); 

Nhưng có các thông số được binded với bối cảnh thực hiện nơi container được đăng ký và không phải là nơi các đối tượng get của intantiated.

Ví dụ như điều này có thể xảy ra?

GlobalContainer.Resolve<IMathService>([FCurrentUser]); 

Tôi biết một số người ủng hộ peoble để có nhà xây dựng rất đơn giản, nhưng có những lúc một tham số constructor trông rõ con đường để đi:

  1. Đối tượng xây dựng cần tham số đối tượng để làm việc, vì vậy tham chiếu phải được thỏa mãn. Tham số này cũng làm cho ràng buộc đó rõ ràng hơn nhiều khi nhìn vào lớp.

  2. Bạn có thể gán tham chiếu trong một phương thức hoặc thuộc tính và tăng và ngoại lệ trong mọi phương thức khác nếu bạn cố gắng sử dụng đối tượng mà không cần thực hiện chuyển nhượng .. Tôi không thích viết loại mã này lãng phí thời gian, chỉ cần sử dụng tham số hàm tạo và kiểm tra ở đó. Ít mã hơn, IMO tốt hơn.

  3. Ngoài ra đối tượng được truyền nội bộ vào đối tượng tạo đối tượng mới bằng cách sử dụng vùng chứa (ví dụ đối tượng Giao dịch) và có một số trạng thái (không phải đối tượng mới mà tôi có thể có với vùng chứa).

+0

Tôi không biết của một tình trạng quá tải của 'TContainer.Resolve 'chấp nhận một tham số mảng trong Spring4D. Tôi có nhớ điều gì không? – menjaraz

+0

@menjaraz Nó chỉ là và ý tưởng về cách nó có thể được thực hiện (chắc chắn nó có thể được donde với RTTI) –

+0

Ok, mà âm thanh như một yêu cầu tính năng. Tại sao không đăng bài đó lên [spring4d Google Group] (http://groups.google.com/group/spring4d)? – menjaraz

Trả lời

7

Tôi đã thêm phần ghi đè của trình giải quyết như trong Unity.

Vì vậy, bạn có thể viết:

program Demo; 

{$APPTYPE CONSOLE} 

uses 
    Classes, 
    Spring.Container, 
    Spring.Container.Resolvers; 

type 
    IUserUpgrader = interface 
    ['{ADC36759-6E40-417D-B6F7-5DCADF8B9C07}'] 
    end; 

    TUser = class(TObject); 

    TUserProcessor = class(TInterfacedObject, IUserUpgrader) 
    public 
    constructor Create(AUser: TUser); 
    end; 

constructor TUserProcessor.Create(AUser: TUser); 
begin 
    Writeln('called constructor with passed user'); 
end; 

begin 
    GlobalContainer.RegisterType<TUserProcessor>.Implements<IUserUpgrader>; 
    GlobalContainer.Build; 

    GlobalContainer.Resolve<IUserUpgrader>(
    TOrderedParametersOverride.Create([TUser.Create])); 

    GlobalContainer.Resolve<IUserUpgrader>(
    TParameterOverride.Create('AUser', TUser.Create)); 

    Readln; 
end. 
0

Bạn có thể kiểm tra chủ đề này: https://forums.embarcadero.com/message.jspa?messageID=440741

tôi đã thực hiện một thực hiện về vấn đề này trong khuôn khổ và sử dụng nó trong mã của tôi. Nếu bạn muốn, tôi sẽ gửi cho bạn. Hãy ghi nhớ rằng đây không phải là cách nó có thể được thực hiện khi nào và nếu họ thêm chức năng như thế này trong codebase. Baoquan có mã của tôi.

Triển khai này cũng xử lý nếu bạn cố gắng giải quyết mà không cần tất cả thông số cần thiết và cung cấp cho bạn ngoại lệ hiển thị các thông số còn thiếu.

Bạn sử dụng nó như thế này:

ServiceLocator.GetService<ISomeObj>(ServiceParameters['paramname1',value1]['paramname2',value2]..); 

Giá trị được lưu giữ như TValue và có thể là bất cứ điều gì.

Đăng ký tham số với lớp học của bạn được thực hiện với các thuộc tính như thế này:

private 
    [ContainerParameter('paramname1')] 
    FYourValue1: ...; 
    [ContainerParameter('paramname2')] 
    FYourValue2: ..; 

Bạn cũng có thể làm

[ContainerParameter] 
FYourValue1:.. 

Nhưng sau đó thông số của bạn có 'FYourValue1' như tên gọi.