TypeRegistration and resolving objects

Topics: Building and extending application blocks, Enterprise Library Core
Oct 14, 2010 at 1:25 PM
Edited Oct 14, 2010 at 1:26 PM

Hello all. I have some problems in registrations. Here are two variants of code:

1st works fine:

 

        public override IEnumerable<TypeRegistration> GetRegistrations()
        {
            yield return
                new TypeRegistration<Device>(
                    () =>
                    new ComDevice()
                        {
                             PortSettings = Container.Resolved<ComPortSettings>(ComSetting)
                        }) {Name = Name};
        }

 

2nd doesn't work(Container.Resolved returns null):

 

        public ComPortSettings getSettings()
        {
            return Container.Resolved<ComPortSettings>(ComSetting);
        }

        public override IEnumerable<TypeRegistration> GetRegistrations()
        {
            yield return
                new TypeRegistration<Device>(
                    () =>
                    new ComDevice()
                        {
                            Structure = GetStructure(),
                             PortSettings = getSettings()
                        }) {Name = Name};
        }

 

 

So the question is why?

Oct 14, 2010 at 7:51 PM

It has to do with what TypeRegistration actually does. The code you entered in that lambda is never executed. Instead, the compiler turns it into an expression tree object. At container configuration time, we pick through the expression looking for "interesting" stuff. However, the possible permutations of things you could put in an expression are enormous, so we didn't even try to handle everything. More specifically, we look for calls to Container.Resolved. But we don't look for calls to Container.Resolved inside another method. In fact, we can't - getSettings doesn't return an expression, it's just a method call as far as the expression is concerned.

Container.Resolved isn't designed to be called. In fact, it actually returns null, which I suspect is what you're getting.

So the second one won't work. If you want to resolve the value of something, do it in the top-level registration, don't try to call a method from inside the type registration method.

 

Oct 15, 2010 at 9:00 AM
Edited Oct 15, 2010 at 9:02 AM

If so, maybe you can tell me how can i resolve some of my problems?

What i have:

Class A; has a1, a2, ... properties

Class B:A; has b1,b2,... properties

Configuration classes:

Class Adata; has a1, a2,... properies

Class Bdata: has b1,b2,... properties

 

As you can see i have parallel ierarchy of classes and configs.

In type registration in Adata i am creating new instance of A and assign all its properties a1,a2,...

In type registration in Bdata i am creating new instance of B and assign all its properties a1,a2,...,b1,b2,...

I don't want to duplicate code with assigning properties a1,a2,...

How can i do this?

I have created some Dictionary, in which i am adding properties values. So in each configuration class i am only adding new properites values. 

Then i create new instance of class using this dictionary. With reflection i set all this properties from dictionary.

All works fine, but only with properties, which values are not resolved. When i try to resolve i get null (you have explained why).

How can i do what i want?

 

Oct 15, 2010 at 2:40 PM

One more question:

How can i register one object for two different types?

for example, i have class B: A, Iinterface

i want to resolve the same instance of this class either by

EnterpriseLibraryContainer.Current.GetInstance<A>()

or

EnterpriseLibraryContainer.Current.GetInstance<Iinterface>()

How should i register it? lambda expression will always create new object...