一、组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1、类型创建RegisterType AutoFac能够通过反射检查一个类型,选择一个合适的构造函数,创造这个对象的实例。主要通过RegisterType<T>() 和 RegisterType(Type) 两个方法以这种方式建立。 ContainerBuilder使用 As() 方法将Component封装成了服务使用。
1 2 |
builder.RegisterType<AutoFacManager>(); builder.RegisterType<Worker>().As<IPerson>(); |
2、实例创建
1 |
builder.RegisterInstance<AutoFacManager>(new AutoFacManager(new Worker())); |
单例 提供示例的方式,还有一个功能,就是不影响系统中原有的单例:
1 |
builder.RegisterInstance(MySingleton.GetInstance()).ExternallyOwned(); //将自己系统中原有的单例注册为容器托管的单例 |
这种方法会确保系统中的单例实例最终转化为由容器托管的单例实例。 3、Lambda表达式创建 Lambda的方式也是Autofac通过反射的方式实现
1 2 |
builder.Register(c => new AutoFacManager(c.Resolve<IPerson>())); builder.RegisterType<Worker>().As<IPerson>(); |
4、程序集创建 程序集的创建主要通过RegisterAssemblyTypes()方法实现,Autofac会自动在程序集中查找匹配的类型用于创建实例。
1 2 |
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()); //在当前正在运行的程序集中找 builder.RegisterType<Worker>().As<IPerson>(); |
5、泛型注册 泛型注册通过RegisterGeneric() 这个方法实现,在容易中可以创建出泛型的具体对象。
1 2 3 4 5 6 |
//泛型注册,可以通过容器返回List<T> 如:List<string>,List<int>等等 builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope(); using (IContainer container = builder.Build()) { IList<string> ListString = container.Resolve<IList<string>>(); } |
6、默认的注册 如果一个类型被多次注册,以最后注册的为准。通过使用PreserveExistingDefaults() 修饰符,可以指定某个注册为非默认值。
1 2 3 4 5 6 7 8 9 |
ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<AutoFacManager>(); builder.RegisterType<Worker>().As<IPerson>(); builder.RegisterType<Student>().As<IPerson>().PreserveExistingDefaults(); //指定Student为非默认值 using (IContainer container = builder.Build()) { AutoFacManager manager = container.Resolve<AutoFacManager>(); manager.Say(); //输出我是一个工人 } |
如果不使用PreserveExistingDefaults(),那么将输出“我是一个学生”。 二、服务 Autofac有三种典型的方式区分服务,同一个服务的不同实现可以由类型,名称和键区分。 1、类型 类型是描述服务的基本方法
1 |
builder.RegisterType<Worker>().As<IPerson>(); //IPerson类型的服务和Worker的组件连接起来,这个服务可以创建Worker类的实例 |
并且上面的服务在自动装备中也有效
1 |
AutoFacManager manager = container.Resolve<AutoFacManager>(); |
2、名字 服务可以进一步按名字识别。使用这种方式时,用 Named()注册方法代替As()以指定名字:
1 |
builder.RegisterType<Worker>().Named<IPerson>("worker"); |
使用Name可以检索服务创建实例:
1 |
IPerson p = container.ResolveNamed<IPerson>("worker"); |
ResolveNamed()只是Resolve()的简单重载,指定名字的服务其实是指定键的服务的简单版本。 3、键 有Name的方式很方便,但是值支持字符串,但有时候我们可能需要通过其他类型作键。 例如,使用枚举作为key:
1 |
public enum DeviceState { Worker, Student } |
使用key注册服务,通过Keyed<T>()方法:
1 |
builder.RegisterType<Student>().Keyed<IPerson>(DeviceState.Student); |
显式检索 使用key检索服务以创建实例,通过ResolveKeyd()方法:
1 |
IPerson p = container.ResolveKeyed<IPerson>(DeviceState.Student); |
ResolveKeyd()会导致容器被当做 Service Locator使用,这是不被推荐的。应该使用IIndex type替代。 IIndex索引 Autofac.Features.Indexed.IIndex<K,V>是Autofac自动实现的一个关联类型。component可以使用IIndex<K,V>作为参数的构造函数从基于键的服务中选择需要的实现。
1 2 3 4 5 6 7 |
builder.RegisterType<Student>().Keyed<IPerson>(DeviceState.Student); using (IContainer container = builder.Build()) { IIndex<DeviceState, IPerson> IIndex = container.Resolve<IIndex<DeviceState, IPerson>>(); IPerson p = IIndex[DeviceState.Student]; p.Say(); //输出我是一个学生 } |
IIndex中第一个泛型参数要跟注册时一致,在例子中是DeviceState枚举。其他两种注册方法没有这样的索引查找功能,这也是为什么设计者推荐Keyed注册的原因之一。 三、自动装配 从容器中的可用服务中选择一个构造函数来创造对象,这个过程叫做自动装配。这个过程是通过反射实现的,所以实际上容器创造对象的行为比较适合用在配置环境中。 1、选择构造函数 Autofac默认从容器中选择参数最多的构造函数。如果想要选择一个不同的构造函数,就需要在注册的时候就指定它。
1 |
builder.RegisterType(typeof(Worker)).UsingConstructor(typeof(int)); |
这种写法将指定调用Worker(int)构造函数,如该构造函数不存在则报错。 2、额外的构造函数参数 有两种方式可以添加额外的构造函数参数,在注册的时候和在检索的时候。在使用自动装配实例的时候这两种都会用到。 注册时添加参数 使用WithParameters()方法在每一次创建对象的时候将组件和参数关联起来。
1 2 |
List<NamedParameter> ListNamedParameter = new List<NamedParameter>() { new NamedParameter("Id", 1), new NamedParameter("Name", "张三") }; builder.RegisterType<Worker>().WithParameters(ListNamedParameter).As<IPerson>(); |
在检索阶段添加参数 在Resolve()的时候提供的参数会覆盖所有名字相同的参数,在注册阶段提供的参数会覆盖容器中所有可能的服务。 3、自动装配 至今为止,自动装配最大的作用就是减少重复配置。许多相似的component无论在哪里注册,都可以通过扫描使用自动装配。
1 |
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).As<IPerson>(); |
在需要的时候,依然可以创建指定的构造函数创建指定的类。
1 |
builder.Register(c => new Worker(2,"关羽")); |
四、程序集扫描 1、扫描 Autofac可以使用约定在程序集中注册或者寻找组件。 Autofac可以根据用户指定的规则在程序集中注册一系列的类型,这种方法叫做convention-driven registration或者扫描。
1 |
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Manager")); |
[…]
View Details最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来。 十年河东十年河西,莫欺少年穷 学无止境,精益求精 今天有点胡思乱想,想遍历MVC Model的属性并取值: 这个方法还是很简单的,通过反射即可遍历属性,我总结的方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
namespace WeiXinApi.CommonCS { public class ForeachClass { /// <summary> /// C#反射遍历对象属性 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="model">对象</param> public static void ForeachClassProperties<T>(T model) { Type t = model.GetType(); PropertyInfo[] PropertyList = t.GetProperties(); foreach (PropertyInfo item in PropertyList) { string name = item.Name; object value = item.GetValue(model, null); } } } } |
下面我们来简单测试下: 新建Model如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class AddressInfo { public int Id { get; set; } public string userName { get; set; } public string userTel { get; set; } public string Addressdetail { get; set; } public int isMoren { get; set; } public AddressInfo() { Id = 1; userName = "陈卧龙"; userTel = "1813707015*"; Addressdetail = "江苏省苏州市工业园区国际科技园"; isMoren = 1; } } |
调用如下:
1 2 3 4 5 6 7 8 9 |
public partial class index : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Response.Redirect("/Home/Login"); AddressInfo model = new AddressInfo(); ForeachClass.ForeachClassProperties<AddressInfo>(model); } } |
测试结果如下: 经过测试,我们可以得到对象的各个属性及对应的值、 其实这块内容输入C# 反射系列,小弟也是误打误撞,撞入了C# 反射,索性每天学一点 from:https://www.cnblogs.com/chenwolong/p/fanshe.html
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class PP { public string a { get; set; } public string b { get; set; } public string c { get; set; } } class Program { static void Main(string[] args) { Hashtable ht = new Hashtable(); ht.Add("a", "utf8"); ht.Add("b", "xxxx"); ht.Add("c", "xxxx"); PP config = new PP(); PropertyInfo[] propertys = config.GetType().GetProperties(); foreach (PropertyInfo property in propertys) { for (int i = 0; i < ht.Count; i++) { property.SetValue(config, ht[property.Name].ToString(), null); } } Console.WriteLine(config.a+"\t"+config.b); Console.ReadLine(); } } |
from:https://www.cnblogs.com/yanglang/p/6830982.html
View Details第一种:ROW_NUMBER() OVER()方式 select * from ( select *, ROW_NUMBER() OVER(Order by ArtistId ) AS RowId from ArtistModels ) as b where RowId between 10 and 20 —where RowId BETWEEN 当前页数-1*条数 and 页数*条数— 执行结果是: 第二种方式:offset fetch next方式(SQL2012以上的版本才支持:推荐使用 ) select * from ArtistModels order by ArtistId offset 4 rows fetch next 5 rows only --order by ArtistId offset 页数*条数 rows fetch next 条数 rows only —- 执行结果是: 第三种方式:--top not in方式 (适应于数据库2012以下的版本) select top 3 * from ArtistModels where ArtistId not in (select top 15 ArtistId from ArtistModels) ——where Id not in (select top 条数*页数 ArtistId from ArtistModels) […]
View Details