不管是老手媽媽還是新手媽媽都看這邊!我們都知道所有的產品裡,小朋友的商品應該是最難選的

小朋友長得又快,過了一個時期又瞬間抽高,怎麼選是一門很大的學問了,也可以避免買錯捶心肝~~1133283357.gif1133283357.gif

因為網路很發達,臉書又這麼普及媽咪買東西更是方便,尤其媽咪一定會到很多親子網站或是親子社團去了解產品的優缺點

不過看了這麼多網站真真假假的資料,【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲)是我在看到最多人推薦的好物

對於我這個精打細算的好媳婦好媽媽來說,真是太棒囉!1133283355.gif

通常有在關注相關婦幼產品的媽媽,不用考慮了,這款是我花有夠多時間才彙整出來的好物,不怕比較的啦

很多媽咪也都大推這款產品,真的很值得入手!

到貨速度也很快,光這一點就大推了!

所以我個人對【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲)的評比如下

質感:★★★★

使用爽感:★★★★☆

性能價格:★★★★☆

趁現在宅經濟發酵,大家又很保護小朋友不隨意出門,網購就變成媽咪們在家的興趣了~

而且廠商優惠只在這個時候~~1133283362.gif1133283362.gif

不然被掃光了也只能怪自己速度不夠快~下次記得手刀加速啊!

詳細介紹如下~參考一下吧

完整產品說明

 

 






品牌名稱

  •  

對象與族群

  • 女性
  • 男性
  • 中性

包裝組合

  • 單入組

類型

  • 重度尿失禁(>300ML)

尺寸

  • M

商品規格

  • 保存期限        3年
    原產地        日本
    規格/容量        10片/包

 

非常推薦【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲)給大家

↓↓↓限量特惠的優惠按鈕↓↓↓

↓↓↓找不到適合的商品嗎,本月好物推薦一起來看吧↓↓↓

標籤註解:

PTT鄉民【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲)限量,團購,限時,週年慶,禮物,優惠,【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲)特價,開箱,比價,活動,好評,推薦

mobile01網友【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲)哪裡便宜,採購,優缺點,試用【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲),好用,CP值,經驗,好康,集購,下殺,免比價,去哪買?,

名人推薦【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲)介紹,部落客,排行,【來復易】極緻防漏呵護透氣紙尿褲M10片/包(搭配成人紙尿褲),體驗,精選,限定,折扣,折價卷,dcard推薦,直播主推薦,網紅推薦熱賣款

熱點新知搶先報

 

昨天有個朋友在微信上問我一個問題:他希望通過動態腳本的形式實現對ASP.NET Core MVC應用的擴展,比如在程序運行過程中上傳一段C#腳本將其中定義的Controller類型註冊到應用中,問我是否有好解決方案。我當時在外邊,回復不太方便,所以只給他說了兩個接口/類型:IActionDescriptorProvider和ApplicationPartManager。這是一個挺有意思的問題,所以回家後通過兩種方案實現了這個需求。 ... 一、實現的效果 我們先來看看實現的效果。如下所示的是一個MVC應用的主頁,我們可以在文本框中通過編寫C#代碼定義一個有效的Controller類型,然後點擊「Register」按鈕,定義的Controller類型將自動註冊到MVC應用中 ... 由於我們採用了針對模板為「{controller}/{action}」的約定路由,所以我們採用路徑「/foo/bar」就可以訪問上圖中定義在FooController中的Action方法Bar,下圖證實了這一點。 ... 二、動態編譯原始碼 要實現如上所示的「針對Controller類型的動態註冊」,首先需要解決的是針對提供原始碼的動態編譯問題,我們知道這個可以利用Roslyn來解決。具體來說,我們定義了如下這個ICompiler接口,它的Compile方法將會對參數sourceCode提供的原始碼進行編譯。該方法返回原始碼動態編譯生成的程序集,它的第二個參數代表引用的程序集。 public interface ICompiler { Assembly Compile(string text, params Assembly[] referencedAssemblies); } 如下所示的Compiler類型是對ICompiler接口的默認實現。 public class Compiler : ICompiler { public Assembly Compile(string text, params Assembly[] referencedAssemblies) { var references = referencedAssemblies.Select(it => MetadataReference.CreateFromFile(it.Location)); var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); var assemblyName = "_" + Guid.NewGuid().ToString("D"); var syntaxTrees = new SyntaxTree[] { CSharpSyntaxTree.ParseText(text) }; var compilation = CSharpCompilation.Create(assemblyName, syntaxTrees, references, options); using var stream = new MemoryStream(); var compilationResult = compilation.Emit(stream); if (compilationResult.Success) { stream.Seek(0, SeekOrigin.Begin); return Assembly.Load(stream.ToArray()); } throw new InvalidOperationException("Compilation error"); } } 三、自定義IActionDescriptorProvider 解決了針對提供原始碼的動態編譯問題之後,我們可以獲得需要註冊的Controller類型,那麼如何將它註冊MVC應用上呢?要回答這個問題,我們得對MVC框架的執行原理有一個大致的了解:ASP.NET Core通過一個由伺服器和若干中間件構成的管道來處理請求,MVC框架建立在通過EndpointRoutingMiddleware和EndpointMiddleare這兩個中間件構成的終結點路由系統上。此路由系統維護著一組路由終結點,該終結點體現為一個路由模式(Route Pattern)與對應處理器(通過RequestDelegate委託表示)之間的映射。 ... 由於針對MVC應用的請求總是指向某一個Action,所以MVC框架提供的路由整合機制體現在為每一個Action創建一個或者多個終結點(同一個Action方法可以註冊多個路由)。針對Action方法的路由終結點是根據描述Action方法的ActionDescriptor對象構建而成的。至於ActionDescriptor對象,則是通過註冊的一組IActionDescriptorProvider對象來提供的,那麼我們的問題就迎刃而解:通過註冊自定義的IActionDescriptorProvider從動態定義的Controller類型中解析出合法的Action方法,並創建對應的ActionDescriptor對象即可。 ... 那麼ActionDescriptor如何創建呢?我們能想到簡單的方式是調用如下這個Build方法。針對該方法的調用存在兩個問題:第一,ControllerActionDescriptorBuilder是一個內部(internal)類型,我們指定以反射的方式調用這個方法,第二,這個方法接受一個類型為ApplicationModel的參數。 internal static class ControllerActionDescriptorBuilder { public static IList<ControllerActionDescriptor> Build(ApplicationModel application); } ApplicationModel類型涉及到一個很大的主題:MVC應用模型,目前我們現在只關注如何創建這個對象。表示MVC應用模型的ApplicationModel對象是通過對應的工廠ApplicationModelFactory創建的。這個工廠會自動註冊到MVC應用的依賴注入框架中,但是這依然是一個內部(內部)類型,所以還得反射。 internal class ApplicationModelFactory { public ApplicationModel CreateApplicationModel(IEnumerable<TypeInfo> controllerTypes); } 我們定義了如下這個DynamicActionProvider類型實現了IActionDescriptorProvider接口。針對提供的原始碼向ActionDescriptor列表的轉換體現在AddControllers方法中:它利用ICompiler對象編譯原始碼,並在生成的程序集中解析出有效的Controller類型,然後利用ApplicationModelFactory創建出代表應用模型的ApplicationModel對象,後者作為參數調用ControllerActionDescriptorBuilder的靜態方法Build創建出描述所有Action方法的ActionDescriptor對象。 public class DynamicActionProvider : IActionDescriptorProvider { private readonly List<ControllerActionDescriptor> _actions; private readonly Func<string, IEnumerable<ControllerActionDescriptor>> _creator; public DynamicActionProvider(IServiceProvider serviceProvider, ICompiler compiler) { _actions = new List<ControllerActionDescriptor>(); _creator = CreateActionDescrptors; IEnumerable<ControllerActionDescriptor> CreateActionDescrptors(string sourceCode) { var assembly = compiler.Compile(sourceCode, Assembly.Load(new AssemblyName("System.Runtime")), typeof(object).Assembly, typeof(ControllerBase).Assembly, typeof(Controller).Assembly); var controllerTypes = assembly.GetTypes().Where(it => IsController(it)); var applicationModel = CreateApplicationModel(controllerTypes); assembly = Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Mvc.Core")); var typeName = "Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerActionDescriptorBuilder"; var controllerBuilderType = assembly.GetTypes().Single(it => it.FullName == typeName); var buildMethod = controllerBuilderType.GetMethod("Build", BindingFlags.Static | BindingFlags.Public); return (IEnumerable<ControllerActionDescriptor>)buildMethod.Invoke(null, new object[] { applicationModel }); } ApplicationModel CreateApplicationModel(IEnumerable<Type> controllerTypes) { var assembly = Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Mvc.Core")); var typeName = "Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModelFactory"; var factoryType = assembly.GetTypes().Single(it => it.FullName == typeName); var factory = serviceProvider.GetService(factoryType); var method = factoryType.GetMethod("CreateApplicationModel"); var typeInfos = controllerTypes.Select(it => it.GetTypeInfo()); return (ApplicationModel)method.Invoke(factory, new object[] { typeInfos }); } bool IsController(Type typeInfo) { if (!typeInfo.IsClass) return false; if (typeInfo.IsAbstract) return false; if (!typeInfo.IsPublic) return false; if (typeInfo.ContainsGenericParameters) return false; if (typeInfo.IsDefined(typeof(NonControllerAttribute))) return false; if (!typeInfo.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) && !typeInfo.IsDefined(typeof(ControllerAttribute))) return false; return true; } } public int Order => -100; public void OnProvidersExecuted(ActionDescriptorProviderContext context) { } public void OnProvidersExecuting(ActionDescriptorProviderContext context) { foreach (var action in _actions) { context.Results.Add(action); } } public void AddControllers(string sourceCode) => _actions.AddRange(_creator(sourceCode)); } 四、讓應用感知到變化 DynamicActionProvider 解決了將提供的原始碼向對應ActionDescriptor列表的轉換,但是MVC默認情況下對提供的ActionDescriptor對象進行了緩存。如果框架能夠使用新的ActionDescriptor對象,需要告訴它當前應用提供的ActionDescriptor列表發生了改變,而這可以利用自定義的IActionDescriptorChangeProvider來實現。為此我們定義了如下這個DynamicChangeTokenProvider類型,該類型實現了IActionDescriptorChangeProvider接口,並利用GetChangeToken方法返回IChangeToken對象通知MVC框架當前的ActionDescriptor已經發生改變。從實現實現代碼可以看出,當我們調用NotifyChanges方法的時候,狀態改變通知會被發出去。 public class DynamicChangeTokenProvider : IActionDescriptorChangeProvider { private CancellationTokenSource _source; private CancellationChangeToken _token; public DynamicChangeTokenProvider() { _source = new CancellationTokenSource(); _token = new CancellationChangeToken(_source.Token); } public IChangeToken GetChangeToken() => _token; public void NotifyChanges() { var old = Interlocked.Exchange(ref _source, new CancellationTokenSource()); _token = new CancellationChangeToken(_source.Token); old.Cancel(); } } 五、應用構建 到目前為止,核心的兩個類型DynamicActionProvider和DynamicChangeTokenProvider已經定義好了,接下來我們按照如下的方式將它們註冊到MVC應用的依賴注入框架中。 public class Program { public static void Main() { Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(web => web .ConfigureServices(svcs => svcs .AddSingleton<ICompiler, Compiler>() .AddSingleton<DynamicActionProvider>() .AddSingleton<DynamicChangeTokenProvider>() .AddSingleton<IActionDescriptorProvider>(provider => provider.GetRequiredService<DynamicActionProvider>()) .AddSingleton<IActionDescriptorChangeProvider>(provider => provider.GetRequiredService<DynamicChangeTokenProvider>()) .AddRouting().AddControllersWithViews()) .Configure(app => app .UseRouting() .UseEndpoints(endpoints => endpoints.MapControllerRoute( name: default, pattern: "{controller}/{action}" )))) .Build() .Run(); } } 然後我們定義了如下這個HomeController。針對GET請求的Index方法會將上圖所示的視圖呈現出來。當我們點擊「Register」按鈕之後,提交的原始碼會通過針對POST請求的Index方法進行處理。如下面的代碼片段所示,在將將提交的原始碼作為參數調用了DynamicActionProvider對象的 AddControllers方法之後,我們調用了DynamicChangeTokenProvider對象的 NotifyChanges方法。 public class HomeController : Controller { [HttpGet("/")] public IActionResult Index() => View(); [HttpPost("/")] public IActionResult Index( string source, [FromServices]DynamicActionProvider actionProvider, [FromServices] DynamicChangeTokenProvider tokenProvider) { try { actionProvider.AddControllers(source); tokenProvider.NotifyChanges(); return Content("OK"); } catch (Exception ex) { return Content(ex.Message); } } } 如下所示的是View的定義。 <html> <body> <form method="post"> <textarea name="source" cols="50" rows="10">Define your controller here...</textarea> <br/> <button type="submit">Register</button> </form> </body> </html> 六、換一種實現方式 接下來我們提供一種更加簡單的解決方案。通過上面的介紹我們知道,用來描述Action方法的ActionDescriptor列表是由一組IActionDescriptorProvider對象提供的,對於針對Controller的MVC編程模型(另一種是針對Razor Page的編程模型)來說,對應的實現類型為ControllerActionDescriptorProvider。 當ControllerActionDescriptorProvider在提供對應ActionDescriptor對象之前,會從作為當前應用組成部分(ApplicationPart)的程序集中解析出所有Controller類型。如果我們能夠讓動態提供給原始碼編程生成的程序集成為其合法的組成部分,那麼我們面對的問題自然就能迎刃而解。添加應用組成部分其實很簡單,我們只需要按照如下的方式調用ApplicationPartManager對象的Add方法就可以了。為了讓MVC框架感知到提供的ActionDescriptor列表已經發生改變,我們還是需要調用DynamicChangeTokenProvider對象的NotifyChanges方法。 public class HomeController : Controller { [HttpGet("/")] public IActionResult Index() => View(); [HttpPost("/")] public IActionResult Index(string source, [FromServices] ApplicationPartManager manager, [FromServices] ICompiler compiler, [FromServices] DynamicChangeTokenProvider tokenProvider) { try { manager.ApplicationParts.Add(new AssemblyPart(compiler.Compile(source, Assembly.Load(new AssemblyName("System.Runtime")), typeof(object).Assembly, typeof(ControllerBase).Assembly, typeof(Controller).Assembly))); tokenProvider.NotifyChanges(); return Content("OK"); } catch (Exception ex) { return Content(ex.Message); } } } 由於我們不在需要自定義的DynamicActionProvider,自然也就不需要對應的服務註冊了。 public class Program { public static void Main() { Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(web => web .ConfigureServices(svcs => svcs .AddSingleton<ICompiler, Compiler>() .AddSingleton<DynamicChangeTokenProvider>() .AddSingleton<IActionDescriptorChangeProvider>(provider => provider.GetRequiredService<DynamicChangeTokenProvider>()) .AddRouting().AddControllersWithViews()) .Configure(app => app .UseRouting() .UseEndpoints(endpoints => endpoints.MapControllerRoute( name: default, pattern: "{controller}/{action}" )))) .Build() .Run(); } } 七、這其實不是一個小問題 有人可能覺得上面我們所做的好像只是一些「奇淫巧計」,其實不然,這裡涉及到MVC應用一個重大的主題,我個人將它稱為「動態模塊化」。對於一個面向Controller的MVC應用來說,Controller類型是應用基本的組成單元,所以其應用模型(通過上面提到的ApplicationModel對象表示)呈現出這樣的結構:Application->Controller->Action。如果一個MVC應用需要拆分為多個獨立的模塊,意味著需要將Controller類型分別定義在不同的程序集中。為了讓這些程序集成為應用的一個有效組成部分,程序集需要封裝成ApplicationPart對象並利用ApplicationPartManager進行註冊。針對應用組成部分的註冊不是靜態的(在應用啟動的時候進行),而是動態的(在運行的任意時刻都可以進行) public void NotifyChanges() { var old = Interlocked.Exchange(ref _source, new CancellationTokenSource()); _token = new CancellationChangeToken(_source.Token); old.Cancel(); } } 五、應用構建 到目前為止,核心的兩個類型DynamicActionProvider和DynamicChangeTokenProvider已經定義好了,接下來我們按照如下的方式將它們註冊到MVC應用的依賴注入框架中。 public class Program { public static void Main() { Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(web => web .ConfigureServices(svcs => svcs .AddSingleton<ICompiler, Compiler>() .AddSingleton<DynamicActionProvider>() .AddSingleton<DynamicChangeTokenProvider>() .AddSingleton<IActionDescriptorProvider>(provider => provider.GetRequiredService<DynamicActionProvider>()) .AddSingleton<IActionDescriptorChangeProvider>(provider => provider.GetRequiredService<DynamicChangeTokenProvider>()) .AddRouting().AddControllersWithViews()) .Configure(app => app .UseRouting() .UseEndpoints(endpoints => endpoints.MapControllerRoute( name: default, pattern: "{controller}/{action}" )))) .Build() .Run(); } } 然後我們定義了如下這個HomeController。針對GET請求的Index方法會將上圖所示的視圖呈現出來。當我們點擊「Register」按鈕之後,提交的原始碼會通過針對POST請求的Index方法進行處理。如下面的代碼片段所示,在將將提交的原始碼作為參數調用了DynamicActionProvider對象的 AddControllers方法之後,我們調用了DynamicChangeTokenProvider對象的 NotifyChanges方法。 public class HomeController : Controller { [HttpGet("/")] public IActionResult Index() => View(); [HttpPost("/")] public IActionResult Index( string source, [FromServices]DynamicActionProvider actionProvider, [FromServices] DynamicChangeTokenProvider tokenProvider) { try { actionProvider.AddControllers(source); tokenProvider.NotifyChanges(); return Content("OK"); } catch (Exception ex) { return Content(ex.Message); } } } 如下所示的是View的定義。 <html> <body> <form method="post"> <textarea name="source" cols="50" rows="10">Define your controller here...</textarea> <br/> <button type="submit">Register</button> </form> </body> </html> 六、換一種實現方式 接下來我們提供一種更加簡單的解決方案。通過上面的介紹我們知道,用來描述Action方法的ActionDescriptor列表是由一組IActionDescriptorProvider對象提供的,對於針對Controller的MVC編程模型(另一種是針對Razor Page的編程模型)來說,對應的實現類型為ControllerActionDescriptorProvider。 當ControllerActionDescriptorProvider在提供對應ActionDescriptor對象之前,會從作為當前應用組成部分(ApplicationPart)的程序集中解析出所有Controller類型。如果我們能夠讓動態提供給原始碼編程生成的程序集成為其合法的組成部分,那麼我們面對的問題自然就能迎刃而解。添加應用組成部分其實很簡單,我們只需要按照如下的方式調用ApplicationPartManager對象的Add方法就可以了。為了讓MVC框架感知到提供的ActionDescriptor列表已經發生改變,我們還是需要調用DynamicChangeTokenProvider對象的NotifyChanges方法。 public class HomeController : Controller { [HttpGet("/")] public IActionResult Index() => View(); [HttpPost("/")] public IActionResult Index(string source, [FromServices] ApplicationPartManager manager, [FromServices] ICompiler compiler, [FromServices] DynamicChangeTokenProvider tokenProvider) { try { manager.ApplicationParts.Add(new AssemblyPart(compiler.Compile(source, Assembly.Load(new AssemblyName("System.Runtime")), typeof(object).Assembly, typeof(ControllerBase).Assembly, typeof(Controller).Assembly))); tokenProvider.NotifyChanges(); return Content("OK"); } catch (Exception ex) { return Content(ex.Message); } } } 由於我們不在需要自定義的DynamicActionProvider,自然也就不需要對應的服務註冊了。 public class Program { public static void Main() { Host.CreateDefaultBuilder() .ConfigureWebHostDefaults(web => web .ConfigureServices(svcs => svcs .AddSingleton<ICompiler, Compiler>() .AddSingleton<DynamicChangeTokenProvider>() .AddSingleton<IActionDescriptorChangeProvider>(provider => provider.GetRequiredService<DynamicChangeTokenProvider>()) .AddRouting().AddControllersWithViews()) .Configure(app => app .UseRouting() .UseEndpoints(endpoints => endpoints.MapControllerRoute( name: default, pattern: "{controller}/{action}" )))) .Build() .Run(); } } 七、這其實不是一個小問題 有人可能覺得上面我們所做的好像只是一些「奇淫巧計」,其實不然,這裡涉及到MVC應用一個重大的主題,我個人將它稱為「動態模塊化」。對於一個面向Controller的MVC應用來說,Controller類型是應用基本的組成單元,所以其應用模型(通過上面提到的ApplicationModel對象表示)呈現出這樣的結構:Application->Controller->Action。如果一個MVC應用需要拆分為多個獨立的模塊,意味著需要將Controller類型分別定義在不同的程序集中。為了讓這些程序集成為應用的一個有效組成部分,程序集需要封裝成ApplicationPart對象並利用ApplicationPartManager進行註冊。針對應用組成部分的註冊不是靜態的(在應用啟動的時候進行),而是動態的(在運行的任意時刻都可以進行)

 

↓↓↓限量特惠的優惠按鈕↓↓↓

↓↓↓更多嬰幼兒產品一起來看吧↓↓↓

 

WWW456TTVVV45TYGQ

 

 

文章來源取自於:

 

 

每日頭條 https://kknews.cc/code/m98y486.html

MOMO購物網 https://www.momoshop.com.tw/goods/GoodsDetail.jsp?i_code=5950527&memid=6000007380&cid=apuad&oid=1&osm=league

如有侵權,請來信告知,我們會立刻下架。

DMCA:dmca(at)kubonews.com

聯絡我們:contact(at)kubonews.com


【還在考慮入手嗎,沒關係,開箱文在這】【玉山pi卡刷卡優惠】【使用後的心得大家都說不錯】
【最新開箱文】 【玉山pi卡刷卡回饋最多】 【ding baby】拋棄式防溢乳墊(一盒-100入)(1)【這產品好多人推薦】 【刷台新銀信用卡享優惠】 【DERMAL】草莓亮膚面膜10入組(人氣面膜)【很多人都問這cp值高嗎?現在告訴你】 【最新推薦好物分享】 法國Altho肌活關健有機精油膏加碼組(S)(1)【網紅也在分享這一個好物】 【刷樂天信用卡享優惠】 【Abuns】居家風鐵板紋62CM大巧拼地墊-附收邊條-多色可選(6片裝-適用0.7坪)【產品開箱文熱騰騰登場】 【這款試用心得跟你分享】 【玉如阿姨】罩顧我內衣※0600藍(托高 包覆 爆乳 大罩杯 不易滑肩 不易簍空 機能 台灣製 E.F.G罩。)

arrow
arrow
    全站熱搜

    這款我很愛 發表在 痞客邦 留言(0) 人氣()