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 :)
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?
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.
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.
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?
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
Anyway, feel free to tell me if you need anything
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?
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.
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
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
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: