The Enterprise Library dependency injection module Unity is a lightweight and scalable dependency injection container that supports constructor injection, attribute injection, and method call injection. You can use it to create enterprise database objects or custom objects. However, there are many differences between the Unity module and other modules in the Enterprise Library:
- You can directly use the dependency injection function of the Unity module without installing the Enterprise Library.
- The Unity module can prepare containers through configuration information, or dynamically create dependencies in the code during running.
- The Unity module does not rely on the core library of the Enterprise Library and the Configuration System of the Enterprise Library. It reads the configuration information in its own built-in method. If necessary, you can also read Unity configuration information from the configuration file of the enterprise database.
The Unity module has the following advantages:
- It provides simple object creation, especially for inherited objects and dependency objects, and provides simple code implementation.
- Supports abstract requirements, allowing developers to determine dependencies during running, or specify dependencies during configuration.
- Added flexibility by delaying the Configuration between components in the container.
- The service positioning capability allows clients to store and cache containers. This is quite useful in ASP. NET. developers can persistently store containers in ASP. NET sessions or applications.
The following will include topics of some columns. You can see if Unity is suitable for your application requirements.
- Common solutions.
- Sample Code
- Highlights of Unity
- When to use the Unity Module
I. Common solutions
The Unity module can solve some problems encountered by developers in component-based development. In modern commercial applications, there are many business objects and components used to implement special functions, and some components can independently implement some functions, such as logs, verification, authorization, caching, and exception handling.
The key to successfully establishing such an application is to complete a decoupled and loosely coupled design. Applications with loose coupling are more flexible and easier to maintain. Similarly, they are easy to test during development. You can forge highly dependent objects, such as database connections, network connections, ERP connections, and rich client interface components, to perform unit tests.
Dependency injection is the main technology used to establish loosely coupled applications. It provides some methods to process dependencies between objects. For example, an object that processes customer information may depend on the object accessing the storage, the object verifying the information, and the object checking whether the user has the update permission. The dependency Injection Technology ensures that the customer class is correctly initialized and loaded with the objects used above, especially when the dependency is abstract.
The following Pattern Defines the architecture and development method for processing this process:
- Inversion of Control (IOC) pattern. This mode supports plug-in architecture, so that the object can query other required objects.
- Dependency Injection (DI) pattern. It is a special IOC mode. It is an interface-oriented programming technology that can modify the behavior of a class, but not by modifying the internal implementation of the class. Developers use interface programming to inject dependent object instances into a container in the class. The methods for injecting object instances include interface injection, constructor injection attribute (setter) injection, and method call injection.
- Interception pattern. This mode introduces an indirect level. Place an object between the client and the real object. There is a proxy between the client and the real object. The client behavior interacts with real objects through a proxy, and other objects to be interacted.
The following functions will be demonstrated:
- Create a Unity container
- Obtains objects of the specified type.
- Get the object of the specified type and Registration Name
- Obtains all objects of a special type.
- Use BuildUp to create objects instead of using containers
- Inject annotation objects to constructors
- Inject annotation objects into attributes (setter)
- Inject annotation objects into method calls
In addition, the sample code of Unity includes other technologies, a simple MVP mode implementation, and an Event Broker Service as a custom container extension.
Sample Code
With the dependency injection framework and reverse control technology, developers can generate custom class instances and object instances that depend on other objects. The Unity module supports these functions. developers can use container configuration injection, constructor injection, property injection, and method call injection to create all dependent object instances.
Unity provides two methods to register the type and ing relationships in the container.
- RegisterType. This method registers a type in the container. When appropriate, the container creates an instance of the specified type. You can use the attribute of the class or call the Resolve method. The lifecycle of the created object is the lifecycle specified in the parameter. If you do not provide the lifecycle parameter, the registered life cycle is short. This means that each time you call the Resolve method, the container will create a new object instance.
Using System;
Using Microsoft. Practices. EnterpriseLibrary. Logging;
Using Microsoft. Practices. Unity;
Namespace BeautyCode. ConApp
{
Public interface IMyService
{}
Public class CustomService: IMyService
{}
/// <Summary>
/// Description of Class4.
/// </Summary>
Public class Class4
{
Public Class4 ()
{
IUnityContainer myContainer = new UnityContainer ();
MyContainer. RegisterType <IMyService, CustomService> ();
IMyService myServiceInstance = myContainer. Resolve <IMyService> ();
}
}
}
- RegisterInstance. This method registers an existing instance type in the container, and the lifecycle can be specified. In the lifecycle, the container returns the existing instance. If no lifecycle is specified, the lifecycle of the instance is controlled by the container.
Using System;
Using Microsoft. Practices. EnterpriseLibrary. Logging;
Using Microsoft. Practices. Unity;
Namespace BeautyCode. ConApp
{
Public interface IMyService
{}
Public class CustomService: IMyService
{}
/// <Summary>
/// Description of Class4.
/// </Summary>
Public class Class4
{
Public Class4 ()
{
IUnityContainer myContainer = new UnityContainer ();
CustomService customerServ = new CustomService ();
MyContainer. RegisterInstance <IMyService> (customerServ );
IMyService myServiceInstance = myContainer. Resolve <IMyService> ();
}
}
}
Constructor Injection
If a developer uses the Unity Resolve Method to initialize a class with a constructor, the constructor has more than one parameter. The parameter type is other custom classes, the Unity container automatically creates the dependent objects described in parameters. For example, the following CustomService class depends on a LoggingService class.
Public class CustomService: IMyService
{
Public CustomService (LoggingService logger)
{
Logger. WriteToLog ("Some Value ");
}
}
When running, the developer uses the container's Resolve method to create a CustomService instance. The container also creates a LoggingService object instance within the CustomService type range.
IUnityContainer myContainer = new UnityContainer ();
CustomService myInstance = myContainer. Resolve <CustomService> ();
Property Injection
In addition to constructor injection, Unity also supports property injection and method call injection. The following describes property injection. A ProductService class has a property called SupplierData. You can add the Denpendency attribute to the property to inject the property.
Public class SupplierData
{
}
Public class ProductData
{
Private SupplierData _ supplier;
[Dependency]
Public SupplierData Supplier
{
Get {return _ supplier ;}
Set {this. _ supplier = var ;}
}
}
Now, if you use Unity to create a ProductData object instance, A SupplierData class instance is automatically created as the property value of the ProductData object.