zoukankan      html  css  js  c++  java
  • nopcommerce笔记2

    有时我们需要故意用错误来求得真相。

    有一个控制器如下:

    public class HomeController : Controller
    {
    //
    // GET: /Home/

    public HomeController(int i)
    {
    }

    public ActionResult Index()
    {
    return View();
    }

    }

    屏蔽了无参数的构造函数,在Application_Start中同时屏蔽NopDependencyResolver:

    protected void Application_Start()
    {
    EngineContext.Initialize(false);
    //set dependency resolver
    var dependencyResolver = new NopDependencyResolver();
    //DependencyResolver.SetResolver(dependencyResolver);

    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

    访问这个action,错误是:

     放开NopDependencyResolver,错误是:

    可以看到屏蔽NopDependencyResolver时,交给

    System.Activator.CreateInstance
    去创建控制器实例

    放开时,交给

    Nop.Web.Framework.Mvc.NopDependencyResolver.GetService
    去创建控制器实例

    通过对错误提示的分析,放开NopDependencyResolver时,纠结在参数不能解析,于是想到给控制器构造函数参数给默认值,果然就通过了,不再有错误。

    public class HomeController : Controller
    {
    //
    // GET: /Home/

    public HomeController(int i=1)
    {
    }

    public ActionResult Index()
    {
    return View();
    }

    }

    切换成屏蔽NopDependencyResolver时,错误依然。

    然后,还有然后,在网上,根据这个网址:

    http://www.nopchina.com/forum.php?mod=viewthread&tid=109

    又思考了一下,既然是ioc,那么去掉默认值,把int的实例注册进去应该是可以的,也就是这样:

    去掉默认值:

    public class HomeController : Controller
    {
    //
    // GET: /Home/

    public HomeController(int i)
    {
    }

    public ActionResult Index()
    {
    return View();
    }

    }

    注册一个int 单例:

    public class MvcApplication : System.Web.HttpApplication
    {
    protected void Application_Start()
    {
    EngineContext.Initialize(false);
    //set dependency resolver
    var dependencyResolver = new NopDependencyResolver();
    DependencyResolver.SetResolver(dependencyResolver);

    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);

    EngineContext.Current.ContainerManager.AddComponentInstance<int>(100, "forhome", Nop.Core.Infrastructure.DependencyManagement.ComponentLifeStyle.Singleton);
    }
    }

    结果是没有错误。

    同时好像发现对int这种注册,必须是ComponentLifeStyle.Singleton,改成ComponentLifeStyle.Transient报错如下:

    可以看见很多流程性的东西,至于100为什么必须是单例,也许可以纠结下去,但我还是打住。上面的图贴出来,就是为了看看调用Application_Start的流程而已。

    然后想到,我注册多个int,效果是怎样的?

    于是:

    控制器:

    public class HomeController : Controller
    {
    //
    // GET: /Home/
    private int n;

    public HomeController(int i)
    {
    n = i;
    }

    public ActionResult Index()
    {
    ViewBag.n = n;
    return View();
    }

    }

    view:

    @{
    ViewBag.Title = "Index";
    }

    <h2>@ViewBag.n</h2>

     Application_Start:

    protected void Application_Start()
    {
    EngineContext.Initialize(false);
    //set dependency resolver
    var dependencyResolver = new NopDependencyResolver();
    DependencyResolver.SetResolver(dependencyResolver);

    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);

    EngineContext.Current.ContainerManager.AddComponentInstance<int>(100, "forhome1", Nop.Core.Infrastructure.DependencyManagement.ComponentLifeStyle.Singleton);


    EngineContext.Current.ContainerManager.AddComponentInstance<int>(999, "forhome2", Nop.Core.Infrastructure.DependencyManagement.ComponentLifeStyle.Singleton);


    EngineContext.Current.ContainerManager.AddComponentInstance<int>(777, "forhome3", Nop.Core.Infrastructure.DependencyManagement.ComponentLifeStyle.Singleton);
    }

    我猜是777,结果是它。

    然后,又想到是否可以在:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
    EngineContext.Current.ContainerManager.AddComponentInstance<HomeController>(new HomeController(2000), "ddd", Nop.Core.Infrastructure.DependencyManagement.ComponentLifeStyle.Singleton);
    }

    果然是2000,只是和上面一样,为什么必须ComponentLifeStyle.Singleton。

    不是话:

    为什么必须是单例?

    回家后又仔细思考,首先我想清楚了为什么必须是ComponentLifeStyle.Singleton。因为AddComponentInstance注册进ioc容器中的本身就是一个实例,不是容器创建出来的,这样的实例,容器是不应该(不是不能)管理它的生命周期的。

    想要一个临时的实例,应该使用注册基类(或接口)和实现类的方法,这样容器依据实现类创建的实例才可以指定为单例或者临时,这种创建出的实例显然只有通过容器才能拿到,因此它的生命周期完全由容器控制是合理的。

    例子如下:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
    EngineContext.Current.ContainerManager.AddComponentInstance<int>(2400, "p1");
    Dictionary<string,string> p = new Dictionary<string,string>();
    p.Add("i", "p1");// i是HomeController构造函数参数名

    EngineContext.Current.ContainerManager.AddComponentWithParameters<Controller, HomeController>(p, "kkk", ComponentLifeStyle.Transient);

    }

    结果是2400。

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
    EngineContext.Current.ContainerManager.AddComponentInstance<int>(2500, "p1");

    EngineContext.Current.ContainerManager.AddComponent<Controller, HomeController>( "kkk", ComponentLifeStyle.Transient);

    }

    是2500。

    其实下面一句是多余的,改成如下也是可以的:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {

    EngineContext.Current.ContainerManager.AddComponentInstance<int>(2500, "p1");

    }

    还有一个很重要的发现:

    NopDependencyResolver 与

    PresentationNop.Web.FrameworkDependencyRegistrar.cs

    中的这个注册是息息相关的:

    //controllers
    builder.RegisterControllers(typeFinder.GetAssemblies().ToArray());

    如果不注册,会使用默认方式生成控制器

    我写这么多,觉得收获主要有:

    1、DependencyResolver.SetResolver :让我们有了干涉Controller实例生成的钩子,还可干涉别的啥,暂时不知道

    2、NopDependencyResolver :让我们可以在Autofac的ioc容器中去发挥对Controller的生成控制

    3、进一步理解了ioc

  • 相关阅读:
    Effective Java 19 Use interfaces only to define types
    Effective Java 18 Prefer interfaces to abstract classes
    Effective Java 17 Design and document for inheritance or else prohibit it
    Effective Java 16 Favor composition over inheritance
    Effective Java 15 Minimize mutability
    Effective Java 14 In public classes, use accessor methods, not public fields
    Effective Java 13 Minimize the accessibility of classes and members
    Effective Java 12 Consider implementing Comparable
    sencha touch SortableList 的使用
    sencha touch dataview 中添加 button 等复杂布局并添加监听事件
  • 原文地址:https://www.cnblogs.com/whwqs/p/3412622.html
Copyright © 2011-2022 走看看