[Lazarus] Inversion of control (IoC) and Dependency injection (DI)
silvioprog
silvioprog at gmail.com
Sun Jan 11 21:12:03 CET 2015
On Mon, Jan 5, 2015 at 5:07 PM, luiz americo pereira camara <
luizmed at oi.com.br> wrote:
> Starting a new thread.
>
> 2015-01-05 15:16 GMT-03:00 silvioprog <silvioprog at gmail.com>:
>
>> On Mon, Jan 5, 2015 at 12:54 PM, Marco van de Voort <marcov at stack.nl>
>> wrote:
>>
>>>
>>> As a first step in the 3.0.0 release process the stable branch was
>>> branched
>>> off to branches/fixes_3_0 and the version number was updated to 3.0.1
>>>
>>> The version in trunk was raised to 3.1.1
>>>
>>> Scripts might need modification accordingly.
>>
>>
>> Good news!
>>
>> Chances of custom attributes[1] (or something like this) in release 3.0?
>> I have plans to use IoC[2] and DI using this feature.
>>
>>
> I created a IoC Container that can be found at
> https://code.google.com/p/luipack/source/browse/trunk/luicomponents/luiioccontainer.pas
> . It has no dependencies.
>
Awesome!
With it is possible to implement Service Locator and Property Injection
> patterns. Constructor Injection is not possible due to lacking of Extended
> RTTI support in fpc.
>
Can you send a small (and isolated) sample showing how to use it?
> While the C# crowd praises the Constructor Injection pattern (
> http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container
> ), i had hard times figuring how it would work in real world / Lazarus
> projects. Also, polluting the constructor signature is not something that
> i like. And finally with Constructor Injection is not possible to use with
> TComponent / TForm
>
> So in the end, i use the service locator and have plans to use Property
> Injection pattern
>
> BTW: Custom Attributes support would help to have a nicer Property
> Injection implementation
>
I've plan to use something like this (CDI inspirations: http://cdi-spec.org
):
The model:
uses
My.Company.MySDK.EntityAttributes, My.Company.MySDK.TableAttributes ...;
type
[Entity]
[Table('products')]
TProduct = class(TObject)
public
[Id][GeneratedValue]
property Id: LongInt ...;
[ManyToOne][JoinColumn('OrderId')]
property OrderId: LontInt ...;
[NotNull][NotEmpty][Size(1, 10)][Unique]
property Name: String ...;
[Nulls][Lenght(100)][Unique]
property Description: String ...;
[MyCustomCurrConversion(TypeInfo(Currency), TypeInfo(String), ',0.00')]
[MyCustomMinMax('Price must be >= %d and <= %d.', [1, 1000])]
property Price: Currency ...;
end;
The DAO:
type
[RequestScoped]
TProductDao = class(TObject)
private
[Inject] property Session: TSession ... ;
[Transational] procedure Add(AProduct: TProduct);
...
end;
...procedure TProductDao.Add(AProduct: TProduct);begin
Session.Save(AProduct);end;
The *produces* (to use external libs like *JCore*):
type
[ApplicationScoped]
TSessionCreator = class(TObject)
private
[Inject] property SessionFactory: TJCoreSession ... ;
[Produces] function GetSession: TSession;
...
end;
...
TSessionCreator.GetSession: TSession;begin
Result := ASessionFactory.OpenSession;end;
TSessionCreator.Close([Disposes]ASession: TSession) {begin if
ASession.IsOpen ASession.Close;end;
The controller:
uses
My.Company.ControllerAttributes ... ;
type
[Controller]
TProcuctController = class(TObject)
public
[Post][Transational] procedure Add([Valid] AProduct: TProduct); //
[Valid]: to validade properties
[Get][Path('./product')][Transational] procedure
List([Pagination('page={[0-9]}&rows={[0-9]}')] AProducts:
TArrayList<TProduct>); // to paginate products
[Inject] property ProductDao: TProductDao ...; // inject DAO
[Inject] property Result: TResponse ...; // inject Response
end;
...
procedure TProcuctController.Add(AProduct: TProduct);begin
ProductDao.Add(AProduct);
Result.SetAttribute(AProduct,
'product').RedirectTo(TProductController).List;end;
procedure TProcuctController.List(AProducts: TArrayList<TProduct>);begin
Result.SetAttribute(AProducts, 'products'); // to create a variable
"products" in my BSP viewend;
The view:
<html>
<ul>
<c:forEach items="${products}" var="product">
<li> ${product.name} - <fmt:currency value="${product.price}"
mask="R$ ,0.00"/></li>
</c:forEach>
</ul>
</html>
But I think that I'll still wait some years to make it possible in Free
Pascal hehe ...
--
Silvio Clécio
My public projects - github.com/silvioprog
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20150111/e7269c03/attachment-0003.html>
More information about the Lazarus
mailing list