您的位置:首页 > 数据库 > Redis

使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射

2018-04-23 18:54 1811 查看

使用Code First建模自引用关系笔记

 

原文链接

一.Has方法:

A.HasRequired(a => a.B);
  1. HasOptional:前者包含后者一个实例或者为null
  2. HasRequired:前者(A)包含后者(B)一个不为null的实例
  3. HasMany:前者包含后者实例的集合

二.With方法:

A.HasRequired(a => a.B);
  1. WithOptional:后者(B)可以包含前者(A)一个实例或者null
  2. WithRequired:后者包含前者一个不为null的实例
  3. WithMany:后者包含前者实例的集合

 

 

 

 

 

 

asp.net core上使用redis探索(1)

 

基于Ubuntu安装redis, 我找的一个很好的网站: 
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-redis-on-ubuntu-16-04
设置redis密码登录, 编辑redis.conf文件:
将requirepass 后面数据改为你想要的密码。

将redis设置为远程可访问, 编辑redis.conf文件:
将bind 127.0.0.1 改为 bind 0.0.0.0

以上是redis本身的配置,下面我来介绍下如何在.net-core上部署并使用redis,以前基于.NET的时候使用的是ServiceStack.Redis来作为驱动,该驱动有在.net-core上使用的版本,但是目前微软官方就提供了基于Redis的分布式存储,就内嵌在.net core里面具体请看:
https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/distributed
可以下载官方示例,我没有使用它。跑了一遍代码,没有成功,就放弃了(而且这个实现太简单了),微软官方还有这个示例,挺好的,我做了参考,虽然也没有应用它, 代码地址:
https://github.com/aspnet/Caching/tree/dev/src/Microsoft.Extensions.Caching.Redis
这个还是可以的,很好,可以看看。
而后,我在网上找到这篇文章,介绍的很好,设计思路也很不错,但是跑起来的时候失败了,不过也是收获很多, 地址:
https://zablo.net/blog/post/asp-net-core-redis-html-cache
随后我找到了一篇很好的实现,代码地址:
https://github.com/jakeuj/Microsoft.Extensions.Caching.Redis
这个的实现是基于Microsoft.Extensions.Caching.Redis(微软自己的redis实现)。还是很好的,作者自己封装了很多,照着打了遍代码,然后再结合上面第3个链接的代码,自己做了点修改,主要还是在Redis的存储函数Set那,多的修改没有做。总算是成功的跑起来了,随后再深入研究下具体的实现,同时结合微软的官方实现来做些自己的修改。
一开始查资料的时候,我算是见识到了。百度出来的东西那是千篇一律,最后直接用bing搜,还是Bing良心点,真是不知道一篇文章被好几十个人转有什么意思,而且原文的实现还是有问题的。网络风气啊....

等自己结合上面的几个链接重新封装下redis的类库,再把代码放上来。

 

 

asp.net mvc控制器激活全分析

 

控制器的激活默认情况下使用反射来实现的,这其中采用了DI,单例等设计模式。对于控制器的主要涉及到如下的类:
ControllerBuilder、DefaultControllerFactory、DefaultControllerActivator(实现了IControllerActivator接口)、DependencyResolver(并没有实现IDependencyResolver,但是有这个接口对象实例)、DefaultDependencyResolver(实现了IDependencyResolver接口,默认采用此类来解析控制器对象)

如上的几个类是控制器激活最重要的类。大概说说过程,备忘,当然也说不了多具体,有个大概思路就好,网上已经很多介绍的文章了。DefaultControllerFactory并不是构造控制器的地方,控制器的构造实在ControllerBuilder中,具体涉及到SetControllerFactory以及GetControllerFactory两个方法,我们可以通过SetControllerFactory来拓展自己的IOC容器,这是第一个可供拓展点。
DefaultControllerActivator类用来激活控制器,我们一般创建自己的MVC框架的时候,都是在这个类实现的ICOntrollerActivator接口的Create方法中,通过获取的控制器对象使用反射来创建控制器实例。当然这是在我们自己创建自己的MVC框架以及不使用第三方IOC容器的时候,就是使用该方法来创建的,而在MVC框架中,控制器实例的创建是延迟到了efaultDependencyResolver类中。这也是第二个可拓展的地方,我们可以在第三方IOC容器中,实现IControllerActivator接口来创建控制器对象。
DefaultDependencyResolver类实现了IDependencyResolver接口,默认的MVC框架实现的IOC容器(基于DI模式)设计的容器。我们就是在这里构造了我们的IOC容器,不过通过阅读源码你会发现,该IOC容器源码其实就是默认使用反射来创建控制器对象。这与上面的DefaultControllerActivator类的作用是一样的。可以参考源码:

Assembly ass = Assembly.Load("ConsoleApp1");//获取bin下的dll
Assembly Loadass = Assembly.LoadFrom(@"E:\laiji\WebApplication1\ConsoleApp1\bin\Debug\netcoreapp2.0\ConsoleApp1.dll");//获取路径下的dll
Assembly Thisass = Assembly.GetExecutingAssembly();//获取本程序集的dll
{
Type T1 = ass.GetType("ConsoleApp1.Hello");
Type T2 = Loadass.GetType("ConsoleApp1.Hello");
Type T3 = Thisass.GetType("ConsoleApp1.Hello");
Type T4 = typeof(Hello);//直接获取类型

object[] Parms = new object[2];//参数列表,必须和构造函数的参数对应
Parms[0] = "ObjectName";
Parms[1] = "ObjectSex";

var data1 = Activator.CreateInstance(T1) as Hello;//未进行转换无法调用下面的方法和赋值,调用无参公有构造函数
data1.Name = "TestMan";
data1.PublicSayHello();

var data2 = Activator.CreateInstance(T1,new object[] { "PublicParmsName"}) as Hello;//未进行转换无法调用下面的方法和赋值,调用无参公有构造函数
data2.PublicSayHello();

//注意,使用的构造方法不同
var PrivateData = ass.CreateInstance(T3.FullName, true, BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic, null, Parms, null, null) as Hello;//调用私有有参构造函数
PrivateData.PublicSayHello();

//调用方法
{
Console.WriteLine("********************调用方法****************");
MethodInfo PublicMethod1 = T1.GetMethod("PublicSayHello", new Type[] { });//调用公有方法,如果方法没有重载可以省略new Type[] { }
PublicMethod1.Invoke(PrivateData, null);//null为参数列表,必须一一对应

MethodInfo PublicMethod2 = T1.GetMethod("PublicSayHello", new Type[] { typeof(int) });//调用公有方法,如果有重载,要在后面加上参数类型列表,必须一一对应
PublicMethod2.Invoke(PrivateData, new object[] { 1 });//null为参数列表,必须一一对应

MethodInfo PrivateMethod1 = T1.GetMethod("PrivateSayHello", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);//调用私有方法
PrivateMethod1.Invoke(PrivateData, null);

MethodInfo PublicMethod3 = T1.GetMethod("PublicGenericSayHello");//调用泛型方法
MethodInfo Newmethod = PublicMethod3.MakeGenericMethod(typeof(int));
Newmethod.Invoke(PrivateData, new object[] { 1 });
}

//修改属性,字段
{
Console.WriteLine("********************修改属性,字段****************");
//1.遍历获取,仅能获取公有属性
foreach (var item in T1.GetProperties())
{
item.SetValue(PrivateData, "SetValueForeach");//设置属性的值,为了方便,将所有属性的值都设为SetValueForeach
}
PrivateData.PublicSayHello();

//2.获取指定属性
PropertyInfo Pt1 = T1.GetProperty("Name");//公有属性
Pt1.SetValue(PrivateData, "SetValueUsePropertyName");
PrivateData.PublicSayHello();

PropertyInfo Pt2 = T1.GetProperty("Sex",BindingFlags.Instance|BindingFlags.NonPublic);//私有属性
Pt2.SetValue(PrivateData, "SetValueUsePropertyNameBySex");
PrivateData.PublicSayHello();

//字段同属性,仅将Property换成Field
}
}
{
Console.WriteLine("********************调用泛型构造函数****************");
//泛型构造函数
Type Tp = ass.GetType("ConsoleApp1.SayHello`2");//后面要带占位符`2
Type NewType = Tp.MakeGenericType(typeof(string), typeof(int));//需要新建一个泛型类型
var Data = Activator.CreateInstance(NewType, new object[] {"FFN","LLN",18 }) as SayHello<string,int>;//使用泛型类型创建实例
Data.PublicSayHello();
}

 

 














内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐