如何去掉S8手机网页广告怎么去掉界面广告

自由、创新、研究、探索
Linux/Windows Mono/DotNet [ Open Source .NET Development/ 使用开源工具进行DotNet软件开发]锐意进取,志存高远.成就梦想,只争朝夕.从你开始,创新世界.【That I exist is a perpetual supprise which is life. Focus on eCommerce】
  在之前的文章中,我们讲过除了ASP.NETCore自带的IOC容器外,如何使用Autofac来接管IServiceProvider进行依赖注入。
  最近老有想法在ASP.NET Mvc Core中实现Controller的属性值的依赖注入,但是找遍了Microsoft.Extensions.DependencyInjection类库也没找到对应的方法,而且查看源代码之后发现其都是针对构造器进行依赖注入的,并没有对属性或字段进行依赖注入。
  官方给我们的两种获取依赖注入结果的方法:ActivatorUtilities.CreateInstance和IServiceProvider.GetService,这两个方法的区别,这里我就不详细阐述了,有兴趣的朋友可以自己去查看一下这两个类的源代码:和,但总得来说两个方法在创建对象时都没有注入属性值。
  简单的调用这两个方法:首先在Startup.ConfigureServices函数中,添加语句services.AddTransient&IUser, MyUser&();
  1. IUser user = ActivatorUtilities.CreateInstance(serviceProvider, typeof(IUser));
  2. IUser user = serviceProvider.GetService(typeof(IUser))
  这两个函数的返回结果都是一样的,而且如果MyUser的构造器中有接口类型的话,两个方法也同样会进行依赖注入,但是都不会对创建出的对象属性进行注入。但是这两个方法还是有原理上的不同,ActivatorUtilities是通过构建ExpressionTree的方式对类型的构造器进行构造并创建出对象的,并使用IServiceProvider注入的构造器;而ServiceProvider则是完全通过依赖注入的生命周期的CallSite,对类型进行递归创建对象的。
  如果非要说那个方法更好的话,其实显而易见IServiceProvider是一个接口,而ActivatorUtilities是一组方法,而且ASP.NET Core中的DI生命周期中到处都是ServiceProvider的身影,它的扩展能力无需解释。
二、使用Autofac
  其使这个例子中使用Autofac就是为了偷懒而已,主要是autofac已经支持属性的依赖注入了。但是确无法直接使用,通过研究ASP.NET Core MVC的源代码,我找到了解决方法,并借助Autofac来完成Controller属性的依赖注入操作。
  在上一篇介绍Autofac文章中提到过,Autofac是通过修改Startup.ConfigureServices函数的返回值,及返回值由void修改成IServiceProvider来完成的。
public IServiceProvider ConfigureServices(IServiceCollection services)
var builder = new ContainerBuilder();
services.AddMvc();
builder.Populate(services);
this.ApplicationContainer = builder.Build();
return new AutofacServiceProvider(this.ApplicationContainer);
  通过返回AutofacServiceProvider类型的IServiceProvider,Autofac就通过装饰模式就接管了ServiceProvider。但是只是接管IServiceProvider以后,我们会发现这并不能注入属性值,经过对ASP.NET Core源代码的研究,整理了如下思路:
  1.找到所有Controller的类型
var manager = new ApplicationPartManager();
manager.ApplicationParts.Add(new AssemblyPart(assembly));
manager.FeatureProviders.Add(new ControllerFeatureProvider());
var feature = new ControllerFeature();
manager.PopulateFeature(feature);
&  通过ApplicationPartManager,ASP.NET Core管理着所有程序组件,这里的AssemblyPart是一个程序集组件,也就是说ASP.NET Core MVC会在这个程序集中查找Controller类型或其它使用的类型。我们也可以通过这个方法来添加一个程序集,用于把MVC的项目拆成两个独立的项目,比如Controller项目和View项目等。
  ControllerFeatureProvider这个类看名字就知道它用于是查找Controller类型的。我们来摘一段它的代码看看:
public void PopulateFeature(IEnumerable&ApplicationPart& parts,ControllerFeature feature)
foreach (var part in parts.OfType&IApplicationPartTypeProvider&())
foreach (var type in part.Types)
if (IsController(type) &&!feature.Controllers.Contains(type))
feature.Controllers.Add(type);
  2.通过Autofac对Controller类型进行注册
builder.RegisterTypes(feature.Controllers.Select(ti =& ti.AsType()).ToArray()).PropertiesAutowired();
  Autofac中通过对ControllerFeature中的Controller进行IOC注册,并使用PropertiesAutowired开启属性注入。
  3.修改默认的Controller创建者,使用Autofac的ServiceProvider完成Controller的创建工作。
  这也是最重要的一步,通过查看源代码ASP.NET Core默认使用DefaultControllerActivator类对Controller进行创建工作;但是找到这个类的Create函数发布它其实调用的是ActivatorUtilities来创建对象的。前面也说过这个的话,在创建类型对象时,IServiceProvdier只负责对构造器中的参数进行查找注入,创建对象的操作还是由ActivatorUtilities来create出来的,这样也就没用利用上autofac替换的ServiceProvider,也就是说ActivatorUtilities并没有扩展点来使用我们提供的方法进行替换,所以才造成了无法注入的问题。
  下面代码添加到Services.AddMvc();之前,如下:
services.Replace(ServiceDescriptor.Transient&IControllerActivator, ServiceBasedControllerActivator&());
  其实就是用ServiceBasedControllerActivator来替换默认的DefaultControllerActivator&;来看看它的源代码吧,一下就明白了:
public object Create(ControllerContext actionContext)
if (actionContext == null)
throw new ArgumentNullException(nameof(actionContext));
var controllerType = actionContext.ActionDescriptor.ControllerTypeInfo.AsType();
return actionContext.HttpContext.RequestServices.GetRequiredService(controllerType);
  这里的RequestServices就是IServiceProvider所以都懂的,这里使用的已经是咱们替换过用Provider了。
  最后再加一个Demo,看看属性User是不是被注入值了:
public class HomeController : Controller
public IUserManager User { set; get; }
public IActionResult Index()
User.Register("hello");
return View();
  ASP.NET Core的源代码实在是学习的好材料,每一个组件都是一个扩展,每一个组件都有一组小部件;真正的组件式开发!  
  DEMO的Git地址:
  GitHub:& 如果觉还可以请Star下, 欢迎一起交流。
  .NET Core 和 YOYOFx 的交流群:&
阅读(...) 评论()
随笔 - 15833
评论 - 1288金钱鳘又称黄唇鱼,目前已经接近濒危灭绝的状态。
赴日游客越来越多,国内游客成为黑心商家的肥肉。
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
  Autofac 结合 Castle DynamicProxy2 功能
  Autofac 不仅作为轻量级高效的 IoC 容器,而且还能很好的与 Castle.DynamicProxy2 结合起来,实现 AOP 功能。
  首先,我们需要定义拦截器,简单的定义可实现 Castle.DynamicProxy.IInterceptor 接口即可。
  添加拦截器
  定义好了拦截器后,如何应用到相关对象呢?有两种方式:
  1)使用 Autofac.Extras.DynamicProxy2.InterceptAttribute 特性将拦截器添加到相关的类或接口上;
  2)使用 ContainerBuilder 的 InterceptedBy() 方法在注册对象的同时添加拦截器。
  如何启用拦截器呢?我们只需要在 IoC 注册启用即可。启用拦截器有三种方式,其中针对 WCF 比较特别,下面来具体分析这几种方式的应用场景:
  基于接口的拦截器
  在注册对象的同时启用 EnableInterfaceInterceptors()方法。
  使用接口的拦截器,在使用特性 [Attribute] 注册时,注册拦截器可注册到接口(Interface)上或其实现类(Implement)上。使用注册到接口上方式,所有的实现类都能应用到拦截器。
  对于以接口方式的注入,Autofac Interceptor 要求类的方法为 public 或 virtual 即可。
  示例代码:
  var builder = new ContainerBuilder();
  builder.RegisterType&SomeType&()
  .As&ISomeInterface&()
  .EnableInterfaceInterceptors();
  builder.Register(c =& new CallLogger(Console.Out));
  var container = builder.Build();
  var willBeIntercepted = container.Resolve&ISomeInterface&();
  于类的拦截器
  在注册对象的同时启用 EnableClassInterceptors()方法。
  对于以类方式的注入,Autofac Interceptor 要求类的方法为必须为 virtual 方法。
  值得注意的是:对于 子类,重写(override)父类的虚方法时,能应用到拦截器。父类可在 IoC 中注册也可不需要注册,但子类必须在 IoC 中注册(对于类的拦截器,类都必须要注册,当然,拦截器也必须要注册)。
  示例代码:
  varbuilder = newContainerBuilder();builder.RegisterType&First& () .EnableClassInterceptors();builder.Register(c =& newCallLogger(Console.Out));
  基于 WCF 的拦截器
  WCF 是一种特殊情况。虽然 WCF Proxy 的服务对象也是一种接口,但是使用 EnableInterfaceInterceptors 不会起作用,因为 .NET 实际上是使用了 类似于接口行为的 System.Runtime.Remoting.TransparentProxy 。因此需要这里需要使用 InterceptTransparentProxy() 方法。
  示例代码:
  var cb = new ContainerBuilder();
  cb.RegisterType&TestServiceInterceptor&();
  cb.Register(c =& CreateChannelFactory()).SingleInstance();
  cb.Register(c =& c.Resolve&ChannelFactory&ITestService&&().CreateChannel())
  .InterceptTransparentProxy(typeof(IClientChannel))
  .InterceptedBy(typeof(TestServiceInterceptor))
  .UseWcfSafeRelease();
  实战一下
  先看看基于接口的拦截器:
  我们先定义一个借口,名为 ICalculater:
  using Autofac.Extras.DynamicProxy2;
  namespace AOP.Interceptors
  //[Intercept(typeof(CalculaterInterceptor))]
  public interface ICalculater
  int Add(int x, int y);
  int Sub(int x, int y);
  然后定义该接口的实现类 Calculater:
  using Autofac.Extras.DynamicProxy2;
  namespace AOP.Interceptors
  //[Intercept(typeof(CalculaterInterceptor))]
  public class Calculater : ICalculater
  public int Add(int x, int y)
  return x +
  public int Sub(int x, int y)
  return x -
  接下来,我们来定义拦截器。这里我们定义了两个连接器,通过这两个拦截器,我们将能很清晰的看到拦截器是如何工作的。
  定义第一个拦截器 CalculaterInterceptor:
  using S
  using Castle.DynamicP
  namespace AOP.Interceptors
  public class CalculaterInterceptor : IInterceptor
  public void Intercept(IInvocation invocation)
  // 在下个拦截器或目前方法处理之前处理
  var args = invocation.A
  Console.WriteLine($&Before: x={args[0]}, y={args[1]}&);
  Console.WriteLine($&Before: Method={invocation.Method.Name}&);
  invocation.SetArgumentValue(0, 5);
  // handle
  invocation.Proceed(); // 调用下一个拦截器,直到最终的目标方法。
  // Post
  Console.WriteLine($&After: TargetType={invocation.TargetType}&);
  Console.WriteLine($&After: ReturnValue={invocation.ReturnValue}&);
  invocation.ReturnValue = (int)invocation.ReturnValue - 2;
  定义第二个拦截器 CalculaterInterceptor2:
  using S
  using Castle.DynamicP
  namespace AOP.Interceptors
  public class CalculaterInterceptor2 : IInterceptor
  public void Intercept(IInvocation invocation)
  var args = invocation.A
  Console.WriteLine($&Before2: x={args[0]}, y={args[1]}&);
  Console.WriteLine($&Before2: Method={invocation.Method.Name}&);
  invocation.Proceed();
  Console.WriteLine($&After2: TargetType={invocation.TargetType}&);
  Console.WriteLine($&After2: ReturnValue={invocation.ReturnValue}&);
  invocation.ReturnValue = (int)invocation.ReturnValue - 1; // 将结果值减去 2
  在 控制台 Main 函数输入我们的结果:
  static void Main(string[] args)
  var builder = new ContainerBuilder();
  builder.RegisterType&Calculater&()
  .As&ICalculater&()
  .EnableInterfaceInterceptors()
  .InterceptedBy(typeof(CalculaterInterceptor), typeof(CalculaterInterceptor2)); // 这里定义了两个拦截器,注意它们的顺序
  builder.RegisterType&CalculaterInterceptor&(); // 注册拦截器
  builder.RegisterType&CalculaterInterceptor2&(); // 注册拦截器2
  var ioc = builder.Build();
  var calculater = ioc.Resolve&ICalculater&();
  var addResult = calculater.Add(2, 3);
  Console.WriteLine($&add result: {addResult}&);
  Console.WriteLine(&-------------------&);
  Console.ReadLine();
  我们看看输出结果:
  这里我们可以看出,执行顺序为CalculaterInterceptor --& CalculaterInterceptor2 --& Target Method --& CalculaterInterceptor2 --& CalculaterInterceptor。拦截器中 invocation.Proceed() 方法用于调用下一个拦截器(若存在),直到最终的目标方法(Target Method)。不过 invocation.Proceed()并不是一定要调用的,例如,对于有返回值的目标方法,我们在拦截器中设置 invocation.ReturnValue 值就可正确执行,这样便不会执行目标方法。在有些场景中,如身份验证、缓存读取等还是特别有用的。
  当然,在 Main() 方法中 Ioc 注册 Caliculater 类型时我们注册了两个拦截器,&.InterceptedBy(typeof(CalculaterInterceptor), typeof(CalculaterInterceptor2))&。我们也可以直接在 Calculater 类型或 ICalculater接口上以特性的形式注册,如上面代码中注释掉的那部分。若是既有在类型上注册,也有在 Autofac 的 Builder 中注册,那么这个拦截器会重复执行。
  基于类的拦截器:
  我们定义两个类 Flight 和其 子类 FlightOfSH:
  public class Flight
  public virtual void Fly(DateTime time)
  Console.WriteLine($&Flight: {time}&);
  public class FlightOfSH : Flight
  public override void Fly(DateTime time)
  Console.WriteLine($&FlightOfSH: Fly={time}&);
  public void Arrive(DateTime time)
  Console.WriteLine($&FlightOfSH: Arrive={time}&);
  这两个类的拦截器:
  internal class FlightInterceptor : IInterceptor
  public void Intercept(IInvocation invocation)
  Console.WriteLine(&Before Fly&);
  invocation.Proceed();
  Console.WriteLine(&After Fly&);
  在 Main 函数中定义代码:
  var builder = new ContainerBuilder();
  builder.RegisterType&Flight&()
  .EnableClassInterceptors().InterceptedBy(typeof(FlightInterceptor));
  builder.RegisterType&FlightOfSH&()
  .EnableClassInterceptors().InterceptedBy(typeof(FlightInterceptor));
  builder.RegisterType&FlightInterceptor&();
  var ioc = builder.Build();
  var flight = ioc.Resolve&Flight&();
  flight.Fly(DateTime.Now);
  var flightOfSH = ioc.Resolve&FlightOfSH&();
  flightOfSH.Fly(DateTime.Now);
  flightOfSH.Arrive(DateTime.Now);
  我们看看输出结果:
  从输出结果中可以发现一个有趣的现在, 子类 FlightOfSH 重写了 Flight 的 Fly 方法,却也调用才拦截器。Arrive() 方法因为是非虚方法,所有拦截器不会在该方法中调用。
  当然,我们这里都是直接在 Autofac 的 Ioc 注册类型时设定的,也可以同上面一样使用 InterceptAttribute 特性来注入。
  对于基于 WCF 的拦截器,大家可以自己试验下。
  这里简单的介绍了 Autofac 与 Castle 动态代理功能结合来实现 AOP 功能,当然,Castle 本身也是个很强大的开源框架,也有很强大的 IoC 功能,不过我还是比较喜欢 Autofac 的 IoC 功能。
  相关文章:
  原文链接:/god--love-you/p/5699632.html
  .NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
欢迎举报抄袭、转载、暴力色情及含有欺诈和虚假信息的不良文章。
请先登录再操作
请先登录再操作
微信扫一扫分享至朋友圈
搜狐公众平台官方账号
生活时尚&搭配博主 /生活时尚自媒体 /时尚类书籍作者
搜狐网教育频道官方账号
全球最大华文占星网站-专业研究星座命理及测算服务机构
主演:黄晓明/陈乔恩/乔任梁/谢君豪/吕佳容/戚迹
主演:陈晓/陈妍希/张馨予/杨明娜/毛晓彤/孙耀琦
主演:陈键锋/李依晓/张迪/郑亦桐/张明明/何彦霓
主演:尚格?云顿/乔?弗拉尼甘/Bianca Bree
主演:艾斯?库珀/ 查宁?塔图姆/ 乔纳?希尔
baby14岁写真曝光
李冰冰向成龙撒娇争宠
李湘遭闺蜜曝光旧爱
美女模特教老板走秀
曝搬砖男神奇葩择偶观
柳岩被迫成赚钱工具
大屁小P虐心恋
匆匆那年大结局
乔杉遭粉丝骚扰
男闺蜜的尴尬初夜
客服热线:86-10-
客服邮箱:&Autofac 是一款优秀的IOC的开源工具,完美的适配.Net特性,但是有时候我们想通过属性注入的方式来获取我们注入的对象,对不起,有时候你还真是获取不到,这因为什么呢?
1.你对Autofac 不太了解,在这个浮躁的社会,没有人会认真的了解每个开源项目,只要求能用就行
2.没有时间了解,你是一个很忙的人,工作很忙,应酬很忙
3.刚开始使用Autofac 还没来得及深入了解就要做项目。
不管是什么原因,总之我们注入的属性就是无法直接由autofac 自动注入,或者说我们希望由Autofac自动注入的属性为Null,这可是很让我们纠结的事情。下面我们就来通过一系列我们可能的操作来还原事情的真相。
真相1:通过registerType注册类型,希望通过属性获取注入的类型。
class Program
static void Main(string[] args)
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new LoggingModule());
builder.RegisterType&Test&();
builder.RegisterType&Test2&();
var container = builder.Build();
Test2 test2 = container.Resolve&Test2&();
test2.Show();
public class Test {
public void Show()
Console.WriteLine("FileName");
public class Test2
public Test Test { get; set; }
public void Show()
if (Test != null)
Test.Show();
我们通过RegisterType注入了两个类型Test和Test2,其中Test2中由一个属性为Test类型的Test变量,我们期望Test会自动注入,我们可以直接使用Test.Show方法,但是现实情况是:
我们期望会被Autofac自动注入的属性为Null,我们的期望落空。既然通过RegisterType无法注入,那么通过Register注入呢,是否可行呢?
class Program
static void Main(string[] args)
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new LoggingModule());
//builder.RegisterType&Test&();
builder.Register(t =& new Test()).As&Test&();
builder.RegisterType&Test2&();
var container = builder.Build();
Test2 test2 = container.Resolve&Test2&();
test2.Show();
public class Test {
public void Show()
Console.WriteLine("FileName");
public class Test2
public Test Test { get; set; }
public void Show()
if (Test != null)
Test.Show();
我们通过Register注入一个实例,最后我们的期望还是落空了,还有一种方式就是通过Module进行注册,这种方式还不行,那就说明autofac的属性注入式骗人的(心里想的),我们来通过Module来实现。
真相3:通过module进行注册
1 class Program
static void Main(string[] args)
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new LoggingModule());
//builder.RegisterType&Test&();
//builder.Register(t =& new Test()).As&Test&();
//builder.RegisterType&Test2&();
var container = builder.Build();
//Test2 test2 = container.Resolve&Test2&();
Test2 ee = new Test2();
ee.Show();
public class Test {
public void Show()
Console.WriteLine("FileName");
public class Test2
public Test Test { get; set; }
public void Show()
if (Test != null)
Test.Show();
public class LoggingModule : Module
private readonly ConcurrentDictionary&string, Test& _loggerC
public LoggingModule()
_loggerCache = new ConcurrentDictionary&string, Test&();
protected override void Load(ContainerBuilder moduleBuilder)
// by default, use Coevery's logger that delegates to Castle's logger factory
moduleBuilder.RegisterType&Test&().As&Test&().InstancePerLifetimeScope();
// call CreateLogger in response to the request for an ILogger implementation
// moduleBuilder.Register(CreateLogger).As&ILogging.ILogger&().InstancePerDependency();
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
var implementationType = registration.Activator.LimitT
// build an array of actions on this type to assign loggers to member properties
var injectors = BuildLoggerInjectors(implementationType).ToArray();
// if there are no logger properties, there's no reason to hook the activated event
if (!injectors.Any())
// otherwise, whan an instance of this component is activated, inject the loggers on the instance
registration.Activated += (s, e) =&
foreach (var injector in injectors)
injector(e.Context, e.Instance);
private IEnumerable&Action&IComponentContext, object&& BuildLoggerInjectors(Type componentType)
// Look for settable properties of type "ILogger"
var loggerProperties = componentType
.GetProperties(BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)
.Select(p =& new
PropertyInfo = p,
p.PropertyType,
IndexParameters = p.GetIndexParameters(),
Accessors = p.GetAccessors(false)
.Where(x =& x.PropertyType == typeof(Test)) // must be a logger
.Where(x =& x.IndexParameters.Count() == 0) // must not be an indexer
.Where(x =& x.Accessors.Length != 1 || x.Accessors[0].ReturnType == typeof(void)); //must have get/set, or only set
// Return an array of actions that resolve a logger and assign the property
foreach (var entry in loggerProperties)
var propertyInfo = entry.PropertyI
yield return (ctx, instance) =&
string component = componentType.ToString();
var logger = _loggerCache.GetOrAdd(component, key =& ctx.Resolve&Test&(new TypedParameter(typeof(Type), componentType)));
propertyInfo.SetValue(instance, logger, null);
我们通过Module注册了Test,但是我们通过断点调试可以看到,我们通过属性注入的还是没有得到,还是为Null,这是不是autofac不支持属性注入,我们在心里只骂坑爹啊。
但是我们仔细看一下会发现一个问题,我们的Test2 是通过New得到的,而不是通过autofac得到,我们并没有将Test2注入到autofac中,是不是因为这个愿意呢?
我们来尝试一下,这可是我最后的机会了,因为除了这个原因我实在想不出还有什么别的原因。
static void Main(string[] args)
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterModule(new LoggingModule());
//builder.RegisterType&Test&();
//builder.Register(t =& new Test()).As&Test&();
builder.RegisterType&Test2&();
var container = builder.Build();
Test2 test2 = container.Resolve&Test2&();
// Test2 ee = new Test2();
test2.Show();
我们修改了一下代码,将Test2也注入到Autofac中,然后通过autofac的resolve获取,奇迹出现了,我们看到了我们注册的类型,在属性注入得到了我们想要的实例。
这不得不说是一个令我激动的事情,因为这个属性得到的实在是太难,让我尝试了很多种,经历了很多次绝望。
所以我发现,如果你要想实现autofac的自动属性注入,由三个步骤,第一个通过module注册你要通过属性获取的类型,第二个,在属性所在的class中,也要注册到autofac中,最后一点,获取属性所在的class的实例必须通过autofac获取,也就是绝对不要通过new来获取,因为autofac的存在就是为了让你在一定程度上减少new的使用。
我们使用过autofac的MVC实现,我们发现在controller中可以得到我们的属性值,那是因为controller已经注册到了autofac中,因为肯定有一句builder。registerController的存在。
所在对于想实现autofac自动属性注入的朋友,一定要记得将类型通过module注入到autofac。并且属性所在的类型必须通过autofac获取,因为我们必须让autofac知道类型的存在,才可能会自动注入。
这是一篇说明文,简短的说明,希望没有高深的知识点,但是如果你不了解,会花费很长时间才可能查找到错误的地方。应验了那句话,知道了不难,不知道了难上加难。
我的座右铭:做架构师,要做牛逼的架构师。
阅读(...) 评论()

我要回帖

更多关于 苹果手机怎去掉广告 的文章

 

随机推荐