Is there a possibility to use PascalMock 1.1 and Emballo DI Container?

27 views
Skip to first unread message

Ejik

unread,
Feb 26, 2010, 10:06:00 AM2/26/10
to Emballo
Hi.
Is there a possibility to use PascalMock 1.1 (http://sourceforge.net/
projects/pascalmock/) and Emballo DI Container togather ?

Magno Machado

unread,
Feb 26, 2010, 11:25:37 AM2/26/10
to Emballo
Well, I haven't ever used PascalMock before, but I have just
downloaded it to see how it works.

As far as I could see, you can certainly use Pascal Mock with Emballo.
There will be no problems.

If you start using Emballo, please let me know... And if you wish some
new feature, or have any suggestion, don't hesitate on telling me :)

Ejik

unread,
Feb 26, 2010, 12:19:22 PM2/26/10
to Emballo
Ive use Emballo, but on delphi7 ((
I saw that Emballo designed only Delphi 2010. Maybe I'll use d2010 in
future projects.

I've refused to use pascalmock due to some troubles with memory leak.
But these're no other nice mock frameworks on delphi/pascal.Maybe i'll
try to use SimpleMock.
Here's such trouble:

Interface IA;
Interface IB;
TA = class (IA);
TB = class (IB)
fA : IA;
end;

On unittest Ive should inject TA into TB. Thats ok (Emballo rock!).
Ive inject IAMock, using pascalmock. But when destroy TB object, TA
mock doesnt destroy due to NoRefCount implementation. There is a
memory leak, FastMM report me.

My second question is:
Will Emballo support constructor injection?

Magno Machado

unread,
Feb 26, 2010, 12:21:06 PM2/26/10
to Emballo
In fact, as far as I could see, you *can* use Pascal Mock with
Emballo, but probably you won't *need* it at all.

In my projects, I don't use Emballo on unit tests.

See these code snippets:
type
IDependency = interface
// guid
end;

IClient = interface
// guid
end;

TClient = class(TInterfacedObject, IClient)
private
FDependency: IDependency;
public
constructor Create(const Dependency: IDependency);
end;

In production code I would use Emballo and it will automatically
resolve the implementation of IClient and also resolve IDependency, so
my code is not coupled to the implementations.
So, in production code I'd do something like:
Client := Emballo.Get<IClient>;

But in test code, I do want to test TClient. And for that, I do need a
mock implementation of IDependency. So, in test code I'd do something
like:
Client := TClient.Create(TMockDependency.Create);
(TMockDependency can be implemented via PascalMock)

As you can see, there's no need for Emballo on unit tests. At least
not in this situation. Maybe there'll be situations where you'll need
Emballo on test code, but it will not be always the case.

So: If you want, you *CAN* use Emballo + PascalMock. You just need to
think if you really need this combination.

Magno Machado

unread,
Feb 26, 2010, 12:36:02 PM2/26/10
to Emballo
Please forget my last message... I was considering you were using
D2010.

Well, the current version of Emballo does support constructor
injection, but it only works with D2010.

Regarding the old version (which is compatible with D7), it will never
support constructor injection (at least not like the new Emballo)
because of the lack of RTTI of Delphi pre-2010.
I'm not supporting this new version anymore because I moved to D2010
and I thought nobody was using it.
Are you actively using Emballo? I can implement some enhancements on
it to support constructor injection, but it'll require some hand work
from you to work.

Ejik

unread,
Feb 26, 2010, 12:36:43 PM2/26/10
to Emballo
Sorry for my bad english ((

Thanks for code!

question 1) constructor of TClient class is:

constructor Create(const Dependency: IDependency);
begin
FDependency := Dependency;
end;
nothing more?

This is manual depedency injection in unittests. yes?

q2) You wrote that in production code you do something like:
Client := Emballo.Get<IClient>;
How I can do this on old version of Emballo? (my checkout was at
30.12.2009)

q3) Using pascal mock is more complexity, but how you test behavour of
mock objects?

Ejik

unread,
Feb 26, 2010, 12:51:46 PM2/26/10
to Emballo
Im actively using Emballo, but not need to do enhancements.
I'll finish my project and i try to install d2010.

Magno Machado

unread,
Feb 26, 2010, 12:54:32 PM2/26/10
to Emballo
>question 1) constructor of TClient class is:
>constructor Create(const Dependency: IDependency);
>begin
> FDependency := Dependency;
>end;
>nothing more?
On the new version, it's just this.

On the old version, it would be like:
constructor TClient.Create;
begin
InjectDependencies(Self);
end;

>This is manual depedency injection in unittests. yes?

This is constructor injection. On unit tests I usually call the
constructor manually, and on production code I let Emballo handle this
automatically for me.

>q2) You wrote that in production code you do something like:
>Client := Emballo.Get<IClient>;
>How I can do this on old version of Emballo? (my checkout was at
>30.12.2009)

You can't :(
As I said, I stopped supporting this old version when I moved to D2010
because I thought nobody was using it, so, all the cool new features
were implemented only on the new v ersion. But I can implement that on
the old version for you, it'll be easy. But the syntax will be:
Client := Emballo.Get(IClient) as IClient;

>q3) Using pascal mock is more complexity, but how you test behavour of
>mock objects?

I didn't knew about PascalMock... I use to code these fake objects
manually

Magno Machado

unread,
Feb 26, 2010, 1:00:25 PM2/26/10
to Emballo
> Im actively using Emballo, but not need to do enhancements.
> I'll finish my project and i try to install d2010.
Good to know this :)

Anyway, feel free to tell me if you need anything

Ejik

unread,
Feb 26, 2010, 1:18:17 PM2/26/10
to Emballo
>>Client := Emballo.Get(IClient) as IClient;
If it'll take near 20-30 min and it does not hinder you, this will be
COOL!

Magno Machado

unread,
Feb 26, 2010, 1:25:51 PM2/26/10
to emb...@googlegroups.com
Ok!
It's really easy, I'll do it tomorrow or the day after

Ejik

unread,
Feb 26, 2010, 1:57:39 PM2/26/10
to Emballo
Thaks a lot!

My last question:
Client1 := Emballo.Get(IClient) as IClient;
Client2 := Emballo.Get(IClient) as IClient;
... and so on

Client1 instance not equal Client2 instance and so on.
This is different instances?

Magno Machado

unread,
Feb 26, 2010, 2:06:17 PM2/26/10
to emb...@googlegroups.com
That deppends on how you configured the IClient factory. You can configure it to always return a new instance, or always return the same instance, or you can implement your own custom strategy

Ejik

unread,
Feb 26, 2010, 2:20:05 PM2/26/10
to Emballo
Thanks for help!!!!

Magno Machado

unread,
Feb 26, 2010, 10:19:02 PM2/26/10
to Emballo
Hi,
I've made the changes....

Now you can do


Client := Emballo.Get(IClient) as IClient;

I had to modify some points of the framework... If you have
implemented a custom IFactory, you'll have to rewrite it.

Sergii Kiselev

unread,
Feb 27, 2010, 11:28:17 AM2/27/10
to emb...@googlegroups.com
Hi.
Thanks for new improvemets!!!!!!!!!!!! Thats great!

1) I use it right way?

Iclass = class
procedure amethod();
end;

procedure Iclass.amethod()
var
emballo : TEmballo;
idep : IDependency;
begin
emballo := TEmballo.create;
idep := emballo.get(IDependency) as IDependency;
// now i can use idep object
end;

This is correct?

2) Could you write some examples about how to use IFactory and IDynamicFactory


--
С уважением,
С.К. mailto:Sergii....@gmail.com

Magno Machado

unread,
Feb 27, 2010, 11:43:35 AM2/27/10
to Emballo
>1) I use it right way?
>Iclass = class
> procedure amethod();
>end;
>procedure Iclass.amethod()
>var
> emballo : TEmballo;
> idep : IDependency;
>begin
> emballo := TEmballo.create;
> idep := emballo.get(IDependency) as IDependency;
> // now i can use idep object
>end;
It will do what you want, but you can make it simpler:
procedure Iclass.amethod()
var
idep : IDependency;
begin

idep := emballo.get(IDependency) as IDependency;
// now i can use idep object
end;

There's a function called Emballo that returns a TEmballo.
In fact, there's no need to use this Emballo function. I could
implement it to work like this:
procedure Iclass.amethod()
var
idep : IDependency;
begin
idep := GetDependency(IDependency) as IDependency;


// now i can use idep object
end;

But I wanted to use a syntax similar to the syntax used on the new
version.

> 2) Could you write some examples about how to use IFactory and IDynamicFactory

TDynamicFactory is an implementation of IFactory that dynamically
instantiates objects given it's metaclass and constructor address.
When you register a factory using this syntax:
RegisterFactory(IDependency, TDependency, @TDependency.Create);
You are using the TDynamicFactory.

But it has some restrictions: The constructor must take no arguments,
and must use the default calling convention.


You can implement IFactory to define you own way of instantiating
objects.

For exemple, you can simulate constructor injection using a custom
implementation of IFactory.
Consider these types:


type
IDependency = interface
// guid
end;

IClient = interface
// guid
end;

TClient = class(TInterfacedObject, IClient)
private
FDependency: IDependency;
public
constructor Create(const Dependency: IDependency);
end;

TClientFactory = class(TInterfacedObject, IFactory)
private
function GetGUID: TGUID;
function GetInstance: IInterface;
end;

implementation

{ TClientFactory }

function TClientFactory.GetGUID: TGUID;
begin
Result := IClient;
end;

function TClientFactory.GetInstance: IInterface;
begin
Result := TClient.Create(Emballo.Get(IDependency) as IDependency);
end;

initialization

RegisterFactory(TClientFactory.Create);

On 27 fev, 13:28, Sergii Kiselev <sergii.kise...@gmail.com> wrote:
> Hi.
> Thanks for new improvemets!!!!!!!!!!!! Thats great!
>
> 1) I use it right way?
>
> Iclass = class
>   procedure amethod();
> end;
>
> procedure Iclass.amethod()
> var
>   emballo : TEmballo;
>   idep : IDependency;
> begin
>   emballo := TEmballo.create;
>   idep := emballo.get(IDependency) as IDependency;
>   // now i can use idep object
> end;
>
> This is correct?
>
> 2) Could you write some examples about how to use IFactory and IDynamicFactory
>

> On 2/27/10, Magno Machado <magn...@gmail.com> wrote:
>
>
>
>
>
> > Hi,
> > I've made the changes....
>
> > Now you can do
> > Client := Emballo.Get(IClient) as IClient;
>
> > I had to modify some points of the framework... If you have
> > implemented a custom IFactory, you'll have to rewrite it.
>
> > On 26 fev, 16:20, Ejik <sergii.kise...@gmail.com> wrote:
> >> Thanks for help!!!!
>

> >> On 26 ôåâ, 22:06, Magno Machado <magn...@gmail.com> wrote:
>
> >> > That deppends on how you configured the IClient factory. You can
> >> > configure
> >> > it to always return a new instance, or always return the same instance,
> >> > or
> >> > you can implement your own custom strategy
>
> >> > On Fri, Feb 26, 2010 at 3:57 PM, Ejik <sergii.kise...@gmail.com> wrote:
> >> > > Thaks a lot!
>
> >> > > My last question:
> >> > > Client1 := Emballo.Get(IClient) as IClient;
> >> > > Client2 := Emballo.Get(IClient) as IClient;
> >> > > ... and so on
>
> >> > > Client1 instance not equal Client2 instance and so on.
> >> > > This is different instances?
>

> >> > > On 26 ôåâ, 21:18, Ejik <sergii.kise...@gmail.com> wrote:
> >> > > > >>Client := Emballo.Get(IClient) as IClient;
>
> >> > > > If it'll take near 20-30 min and it does not hinder you, this will
> >> > > > be
> >> > > > COOL!
>

> Ñ óâàæåíèåì,
>  Ñ.Ê.                          mailto:Sergii.Kise...@gmail.com

Sergii Kiselev

unread,
Feb 27, 2010, 12:05:52 PM2/27/10
to emb...@googlegroups.com
Thanks for help!!!

1)
>>function Emballo: TEmballo;
>>begin
>> Result := Nil;
>>end;
Nice implementation of global function "Emballo"!!! I'll refactor my
code now, change to emballo.get...

2) How can i use emballo to resolve singletons to me? Prebuild factories?

sorry for my bad english((


On 2/27/10, Magno Machado <mag...@gmail.com> wrote:

Magno Machado

unread,
Feb 27, 2010, 2:59:10 PM2/27/10
to emb...@googlegroups.com
>2) How can i use emballo to resolve singletons to me? Prebuild factories?
It will act like a singleton, but you'll have to instantiate the object yourself...
My intention when I created this pre buit factory was to use on unit tests: You would instantiate a mock object and register on the framework. When your client class requests that interface, it would receive the mock.
But when I started using constructor injection, I didn't had this need anymore.

On the new emballo, we have better support for singleton. You register your interfaces with this syntax:
RegisterFactory(IDependency, TDependency).Singleton.Done;

When IDependency is requested the first time, it will be instantiated and cached. Then, everytime IDependency is requested again, the cached instance is returned.

It is implemented by a IFactory which uses the decorator pattern. I'll move it to the old version so that you can use it..
Reply all
Reply to author
Forward
0 new messages