Interpretation of Microsoft objectbuilder: Construct a lightweight dependency injection container (3) Locator

Source: Internet
Author: User

In the previous section, we made a simple container to basically implement registration and query of types/objects.CodeCurrently it is relatively stable, and there is no need to deal with various factory instances or understand the ing between interfaces and factories. However, the containers we implement have some problems:

1) Each interface type can only register one corresponding component instance (the interface type is the key in the dictionary, and the key cannot be repeated. The locator of Microsoft objectbuilder uses the key/component ID to register the key)

2) There is only one container layer. The locator of Microsoft objectbuilder implements a multi-level chain table structure container. We will analyze the advantages and disadvantages of such a hierarchical container.

3) components referenced in the container are strongly referenced, which may cause memory leakage.

For a simple example, the main code is very long or the execution time is very long. In the main code, we register and use components that support the Ifirst interface from the container, this component has never been used since then, and the container object has a very long life cycle in our code, because of the add method in the iner, our inner dictionary keeps a strong reference to this component, so that the Garbage Collector cannot clean up the memory of this component normally, resulting in Memory leakage.

○ Memory leakage

In. there are many causes of Memory leakage in. net. For example, the dispose mode is incorrect. Short-lived objects are strongly referenced to long-lived objects, the event handler function is registered using the + = method, but not using the-= logout event function...

For the concepts and detection of. Net Memory leakage, refer to the examples in msdn. Net CLR profile and stackoverflow.

Http://msdn.microsoft.com/en-us/library/ff650691.aspx

Http://stackoverflow.com/questions/20386/memory-leaks-in-net

○ Strong reference/weak reference

For more information about weakreference, see the following link:

Http://msdn.microsoft.com/en-us/library/system.weakreference.aspx

The key of weakreference is that references between objects do not affect normal garbage collection, and weakreference classes are also available in Java.

 

So how can we modify our container to solve the above problems?

1) modify the inner object and change it to a weak reference key/object.

Dictionary <tkey, weakreference> Inner;

2) due to the introduction of weakreference, the original dictionary Code cannot meet the needs of the container. Therefore, you must customize your own dictionary. The main reason is that the objects stored in dictionary may already be empty (because they are weak references and can be recycled by garbage collection) and must be empty before reading.

3) expand a single iner to a linked list and support the iner hierarchy.

4) modify the key type from type to object. Multiple instance types can be registered on the same interface. The new key is type + id.ArticleContinue analysis ).

5) Expand the container interface and divide the container into read-only/read-write (think about why the design is like this)

Next we will analyze the locator code in objectbuilder.

 

1 weakrefdictionary

Weakrefdictionary we just analyzed that it is actually the encapsulation of the dictionary <tkey, weakreference>. The main reason why we didn't use it directly is that we introduced weakfeference, empty objects must be considered during registration and cancellation.

Where

1) encodenullobject, decodenullobject is the function for registering an instance as a null handler. It mainly processes null as our custom null type nullobject and is called in add and tryget.

2) cleanabandoneditems is called in the count method, which will clear the object instances that have been recycled.

Weakrefdictionary implements methods and attributes such as Count, add, remove, containskey, tryget/trygetvalue, ienumerable <keyvaluepair <tkey, tvalue> and so on in the same general dictionary <tkey, tvalue>.

In fact, readers can write their own weakrefdictionary code by referring to the dictionary interface method. Let's take tryget as an example,

 Public     Bool  Tryget (tkey key,  Out  Tvalue)
{
Value = Default (Tvalue );
Weakreference WR;
// Directly call the trygetvalue of the dictionary
If ( ! Inner. trygetvalue (key, Out WR ))
Return False ;
// Use the wekref. Target activity to reference the target object
Object Result = Wr. target;
// The target instance is empty.
If (Result = Null )
{
Inner. Remove (key );
Return False ;
}
// Call decodenullobject to process null objects
Value = Decodenullobject < Tvalue > (Result );
Return True ;
}

2 ireadablelocator Interface

 Public     Interface  Ireadablelocator: ienumerable  <  Keyvaluepair  <  Object  ,  Object  > 
{
Int Count { Get ;}
Ireadablelocator parentlocator { Get ;}
Bool Readonly { Get ;}
Bool Contains ( Object Key );
Bool Contains ( Object Key, searchmode options );
Titem get < Titem > ();
Titem get < Titem > ( Object Key );
Titem get < Titem > ( Object Key, searchmode options );
Object Get ( Object Key );
Object Get ( Object Key, searchmode options );
Ireadablelocator findby (Predicate < Keyvaluepair < Object , Object > Predicate );
Ireadablelocator findby (searchmode options, predicate < Keyvaluepair < Object , Object > Predicate );
}

The ireadablelocator interface extracts the "read" method in the container object in the previous example, and adds support for the chain table hierarchy of the container: ireadablelocator parentlocator saves references to the parent container. Searchmode enumeration supports cascading search for hierarchical containers.

The last two methods are ignored for the moment. Other methods are intuitive. For details, refer to the container object we wrote.

3 ireadwritelocator Interface

The ireadwritelocator interface extracts the "write" method in the container object in the previous example, which is very simple.

 
VoidAdd (ObjectKey,ObjectValue );

BoolRemove (ObjectKey );

4 readablelocator (abstract class)

As an abstract class implementing ireadablelocator, it only implements some code about polymorphism/generics, such

Titem get <titem> (), titem get <titem> (Object Key), etc,

The benefit of this design is that the locator storage mechanism weakrefdictionary is separated from the readablelocator code. locator can be seen as a special case of the adapter mode and contains the weakrefdictionary instance. Readers can use other types of dictionary to implement the iner for specific purposes, and the code changes are very small.

5 readwritelocator (abstract class)

As an abstract class implementing ireadwritelocator, It inherits from the readablelocator abstract class and adds methods for "writing" Container

6 Locator

It inherits readwritelocator and adds references to weakrefdictionary to implement Microsoft container. Its main code is the encapsulation of weakrefdictionary with no complicated logic.

Why is it so tedious for Microsoft to separate interfaces into read/write classes and use abstract classes to encapsulate code?

The main reasons are as follows:

1) interfaces and implementations are separated for better scalability

2) comply with the single responsibility Design Principles of interfaces

3) the code in the class looks concise, intuitive, and easy for unit testing.

There are many examples of such design policies in. NET Framework.

So far, we have analyzed the optimized container locator implemented by Microsoft for the defects of our container. Its functions are the same as those of the container and mainly support object registration and cancellation, this provides the underlying support for dependency injection for the builder we will talk about later.

From the perspective of locator code, the container implemented by Microsoft well follows the design principles such as interface/abstract programming.

Locator in objectbuilderSource code

Http://files.cnblogs.com/huyq2002/ObjectBuilder (locator).zip

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.