IL接口和类的属性

示例二,多个注入:

            //定义类型
            TypeBuilder typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public);
            typeBuilder.AddInterfaceImplementation(typeof(IMail));
var container = new UnityContainer();
container.RegisterType<ICar, BMW>();
container.RegisterType<ICar, Audi>("LuxuryCar");

// Register Driver type            
container.RegisterType<Driver>("LuxuryCarDriver", 
                new InjectionConstructor(container.Resolve<ICar>("LuxuryCar")));

Driver driver1 = container.Resolve<Driver>();// injects BMW
driver1.RunCar();

Driver driver2 = container.Resolve<Driver>("LuxuryCarDriver");// injects Audi
driver2.RunCar();

4、定义A属性的get方法和set方法,get和set方法和普通的方法创建相同,用TypeBuilder的DefineMethod创建。示例代码如下:

完整请参考:

图片 1图片 2

View Code

2、通过以上代码我们可以根据要求先定义字段_a、常量ConstField(在构造函数过程中未使用到,帮组了解类属性的创建)以及给类加上序列化标签,属性可以通过TypeBuilder的DefineField创建,而序列化标签需要通过TypeBuilder的CustomAttributeBuilder去创建,示例代码如下:

图片 3图片 4

6、最后是定义方法。

图片 5图片 6

            //定义属性A
            PropertyBuilder propertyABuilder = typeBuilder.DefineProperty("A", PropertyAttributes.None, typeof(int), null);
            CustomAttributeBuilder desAttributeBuilder = new CustomAttributeBuilder(typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "属性A" });
            propertyABuilder.SetCustomAttribute(desAttributeBuilder);//字段描述

相关定义不变,将使用部分代码改为:

到这一步一个动态类包含的属性、构造函数以及方法就创建完成。可以借助reflector看下生成的结果。如下:

View Code

View Code

var container = new UnityContainer();

container.RegisterType<Driver>(new InjectionConstructor(new object[] { new Audi(), "Steve" }));

var driver = container.Resolve<Driver>(); // Injects Audi and Steve
driver.RunCar();

图片 7图片 8

相关定义的代码不变,将使用部分的代码改为:

            //定义方法
            MethodBuilder methodAddBuild = typeBuilder.DefineMethod("Add", MethodAttributes.Public, typeof(Int32), new Type[] { typeof(int) });
            ILGenerator addIL = methodAddBuild.GetILGenerator();
            addIL.Emit(OpCodes.Ldarg_0);
            addIL.Emit(OpCodes.Ldfld, aField);
            addIL.Emit(OpCodes.Ldarg_1);
            addIL.Emit(OpCodes.Add);
            addIL.Emit(OpCodes.Ret);

图片 9图片 10

View Code

View Code

  通过这篇文章我们了解到了动态类的创建,也了解到了接口的使用。从这两个示例其实可以拓展出很多的东西比如继承、属性绑定自定义标签、虚方法的重写......以后再一一分享
示例代码下载:IL-3

图片 11图片 12

图片 13图片 14

public class Driver
{
    private ICar _car = null;
    private string _name = string.Empty;

    public Driver(ICar car, string driverName)
    {
        _car = car;
        _name = driverName;
    }

    public void RunCar()
    {
        Console.WriteLine("{0} is running {1} - {2} mile ", 
                        _name, _car.GetType().Name, _car.Run());
    }
} 

View Code

示例一,正常使用:

View Code

View Code

            //定义构造函数
            ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { typeof(Int32) });

            ILGenerator constructorIL = constructorBuilder.GetILGenerator();
            constructorIL.Emit(OpCodes.Ldarg_0);
            constructorIL.Emit(OpCodes.Ldarg_1);
            constructorIL.Emit(OpCodes.Stfld, aField);
            constructorIL.Emit(OpCodes.Ret);
var container = new UnityContainer();

container.RegisterType<ICar, Audi>();
container.RegisterType<ICarKey, AudiKey>();

var driver = container.Resolve<Driver>();
driver.RunCar();
            //定义类可序列化
            CustomAttributeBuilder serializable = new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new Type[] { });
            typeBuilder.SetCustomAttribute(serializable);

            //定义常量
            FieldBuilder fieldConst = typeBuilder.DefineField("ConstField", typeof(string), FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.Literal);
            fieldConst.SetConstant("const");

            //定义字段_a
            FieldBuilder aField = typeBuilder.DefineField("_a", typeof(int), FieldAttributes.Private);
            aField.SetConstant(0);

示例四,多个构造函数:

View Code

container.RegisterType<Driver>(new InjectionConstructor(new Ford()));

//or 

container.RegisterType<ICar, Ford>();
container.RegisterType<Driver>(new InjectionConstructor(container.Resolve<ICar>()));

图片 15

图片 16图片 17

            MethodBuilder sendMailBuilder = typeBuilder.DefineMethod("SendMail", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(string), null);
            //定义接口
            ILGenerator mailIL = sendMailBuilder.GetILGenerator();
            LocalBuilder resultStr = mailIL.DeclareLocal(typeof(String));
            mailIL.Emit(OpCodes.Nop);
            mailIL.Emit(OpCodes.Ldstr, "Send Success1");
            mailIL.Emit(OpCodes.Stloc_0);
            mailIL.Emit(OpCodes.Ldloc_0);
            mailIL.Emit(OpCodes.Ret);

我们使用Resolve来解析我们想要的调用对象,在这里是Driver。

图片 18图片 19

示例五,基类型作为构造函数参数:

通过以上信息可以定义接口实现的方法,接口实现就和之前例子定义的方法实现一样。示例代码如下:

public interface ICar
{
    int Run();
}

public class BMW : ICar
{
    private int _miles = 0;

    public int Run()
    {
        return ++_miles;
    }
}

public class Ford : ICar
{
    private int _miles = 0;
    public int Run()
    {
        return ++_miles;
    }
}

public class Audi : ICar
{
    private int _miles = 0;

    public int Run()
    {
        return ++_miles;
    }

}
public class Driver
{
    private ICar _car = null;

    public Driver(ICar car)
    {
        _car = car;
    }

    public void RunCar()
    {
        Console.WriteLine("Running {0} - {1} mile ", _car.GetType().Name, _car.Run());
    }
}

  反编译发现,接口实现是带有override关键字的。而在定义实现方法时候如果不带上virtual属性又会提示接口未实现。。。。。。

View Code

5、构造函数的创建,构造函数是通过TypeBuilder的DefineConstructor去获取,构造函数包含一个参数并赋值给_a,示例代码如下:

本文由金沙官网线上发布于编程,转载请注明出处:IL接口和类的属性

您可能还会对下面的文章感兴趣: