The use of C# Unity framework (1)

Unity

The Unity framework is a commonly used IOC framework in C#. Learning Unity suggests that you should have a certain understanding of IOC. Like other IOC frameworks, Unity's role is to use dependency injection and inversion of control to achieve a high degree of decoupling.

Use of Unity

Getting started with Unity is relatively simple. Unlike Java's Spring, which requires a lot of configuration. So let’s learn how to use it right away.

1. Project construction

1. Interface

public interface IFood
{
    
    
    string Name {
    
     set; get; }
}

2. Implementation class

public class Banana:IFood
{
    
    
    public string Name {
    
     get; set; } = string.Empty;
}
 public class Apple:IFood
{
    
    
    public string Name {
    
     get; set; } = string.Empty;
}
public class Beef:IFood
{
    
    
    public string Name {
    
     get; set; } = string.Empty;
}

1. Construction of IOC container

Since it is a program that manages the use of objects, of course, there must be a container to manage the creation and preservation of objects. In this way, you can select the objects you need at the moment of need.

public static IUnityContainer Container = new UnityContainer();

2. Registration and acquisition of instances

1. How to register and obtain the full version

IUnityContainer RegisterInstance(Type type,string name, object instance,LifetimeManager lifetime);

By Containercalling this method, an instance can be registered in the container.
Parameter 1: typeSpecify the type of the instance.
Parameter 2: nameSpecify the name of the instance.
Parameter 3: instanceSpecify the instance to be registered.
Parameter 4: lifetimeSpecify the life cycle of the instance (Unity has 6 built-in lifetime management models. The default is to TransientLifetimeManagerobtain a new instance every time )

public static T Resolve<T>(string name);

By Containercalling this method, an instance of the specified name can be obtained.
Generic: Tspecify the type of the instance to be obtained
Parameter 1: namespecify the name of the instance to be obtained

ContainerAn instance with this name will be returned in the container that matches the type.

class Program
{
    
    
	//新建IOC容器
    public static IUnityContainer Container = new UnityContainer();

	public static void Main(string[] args)
    {
    
    
        Banana banana = new Banana
        {
    
    
            Name = "香蕉"
        };
        Apple apple = new Apple
        {
    
    
            Name = "苹果"
        };
        //注册IFood类型的实例banana到容器中,key为banana。
        //TransientLifetimeManager表示每次获取该类型都是一个新实例。
        Container.RegisterInstance(typeof(IFood), "banana", banana,
         new TransientLifetimeManager());
         //获取IFood类型,key为banana的实例
        food = Container.Resolve<IFood>("banana");
        //因为每次获取该类型都新创建一个实例,因此名字不是香蕉而是空字符串。
        Console.WriteLine("取得的食物是:" + food.Name);
        Console.ReadLine();
	}
}
2. The life cycle of the instance

Abstract class of life cycle: LifetimeManagerThis abstract class describes the life cycle of an instance.
There are 6 sub-classes that represent 6 different life cycles of an instance.

TransientLifetimeManagerGenerate a new type object instance for each request. (Default)
When this parameter is used, every instance obtained is brand new.
ContainerControlledLifetimeManagerEach request is a registered instance (singleton mode)
. Singleton mode can be realized when this parameter is used. The instance obtained each time is the same.
For others, please read Object lifetime management in Unity container . No expansion here.

3. Simplified method

1) Omit the life cycle
IUnityContainer RegisterInstance( Type type, string name, object instance);

After the life cycle is omitted, other parameter functions remain unchanged, and the life cycle will use the default life cycle.
That is, each acquisition is a brand new instance.

2) Omit the name
IUnityContainer RegisterInstance(Type type,object instance);

After the instance name is omitted, the named instance acquisition method cannot be used.
Only use to public static T Resolve<T>();obtain an instance of this type.

When using keys to obtain instances, you can accurately obtain different instances of the same type.

When the key is not used, only one instance of that type can be stored in a type. The second registration will overwrite the previously registered instance.

If you use the same key to register the instance. Then it will overwrite the previously registered instance of this key.

public static void Main(string[] args)
{
    
    
    //注册
    Banana banana = new Banana
    {
    
    
        Name = "香蕉"
    };
    Apple apple = new Apple
    {
    
    
        Name = "苹果"
    };
    Beef beef = new Beef
    {
    
    
        Name = "牛肉"
    };
    //注册IFood类型的实例banana。
    Container.RegisterInstance(typeof(IFood),banana);
    //使用
    //获取IFood类型的实例
    var food =Container.Resolve<IFood>();
    Console.WriteLine("取得的食物1是:"+food.Name);
    //为容器注入新的IFood类型实例会覆盖之前注册的IFood实例
    Container.RegisterInstance(typeof(IFood),apple);
    //获取IFood类型的实例
    food = Container.Resolve<IFood>();
    Console.WriteLine("取得的食物2是:" + food.Name);

    //注册一个key为'banana'的实例
    Container.RegisterInstance(typeof(IFood), "banana", banana,
        new ContainerControlledLifetimeManager());
    food = Container.Resolve<IFood>("banana");
    Console.WriteLine("取得的食物1是:" + food.Name);

    //再注册一个key为'banana'的实例
    Container.RegisterInstance(typeof(IFood), "banana", beef,
        new ContainerControlledLifetimeManager());
    food = Container.Resolve<IFood>("banana");
    Console.WriteLine("取得的食物2是:" + food.Name);
    Console.ReadLine();
}

Result:
Insert picture description here
3) Omit type
IUnityContainer RegisterInstance(object instance);

When the type is not specified, the default declaration is the type of the registered instance.

public static void Main(string[] args)
{
    
    
     //注册
     Banana banana = new Banana
     {
    
    
         Name = "香蕉"
     };
     //注册IFood类型的实例banana。
     Container.RegisterInstance(banana);
     //使用
     //获取IFood类型的实例
     var food =Container.Resolve<Banana>();
     Console.WriteLine("取得的食物1是:"+food.Name);
}

IFoodAn instance of the type cannot be obtained at this time . Because bananas are of Bananatype. But if you declare bananas as a IFoodtype, you can also use IFoodtype acquisition.
This shows that the type used when registering in the container is the type when the instance was declared, not the type of the instance itself.

4) Use generics to specify the registration type and
IUnityContainer RegisterInstance<T>(object instance);only specify the type and instance.

IUnityContainer RegisterInstance<T>(string name, object instance);Specify the type, key value and instance.
IUnityContainer RegisterInstance<T>(string name, object instance,LifetimeManager lifetime);Specify the type, key value, instance, and life cycle.
Move the type of the instance from the parameter to the method generic. The parameters are reduced, and the actual use method remains unchanged.

Later, we will introduce other registration methods and configuration methods. To be continued~

Guess you like

Origin blog.csdn.net/qq_42068856/article/details/106181178