اجرای ASP.NET 5 در لینوکس
استفاده از ASP.NET vNext با Docker
Docker is a popular open source containerization tool.
یکی از بهترین کاربردهای React، ترکیب کردن چند کامپوننت برای ساخت یک کامپوننت است. کامپوننت ساخته شده به این روش هر چند مشخص است چه کاری انجام میدهد، اما خود کامپوننت تگها را نمیسازد و شبیه یک لگو با قطعات مختلف است. مثلا در جایی از سایت میخواهیم اطاعات کاربری را نمایش دهیم. این اطلاعات به زیر مجموعههایی تقسیم میشوند؛ مثل اطلاعات شخصی، اطلاعات مربوط به شغل، اطلاعات تماس و عکس. به جای جمع کردن همه موارد در یک کامپوننت بهتر است هر بخش ویژه را در یک کامپوننت جدا و مستقل نمایش داده و ایجاد کنیم. با این کار از هر کامپوننت میشود به صورت جداگانه در قسمتهای دیگر سایت استفاده کرد. مثلا نمایش عکس کاربر به تنهایی در بخشهای دیگر سایت. در نهایت با این روش حجم کدها هم کمتر میشود. کامپوننتی که از اجزای کوچکتر ساخته میشود، مالک کامپوننتهای زیر مجموعه خود است.
کامپوننت مالک میتواند دادههای ورودی را برای اجزای سازنده خود به صورت یک سویه (one-way data binding) فراهم کند. گاهی دادههای مورد نیاز فرزندان، به طور مستقیم به مالک و از مالک به طور غیر مستقیم به فرزندان ارسال میشود. اما ممکن است لازم باشد که دادهها در اثر محاسبه در کامپوننت مالک، ایجاد و نتیجه به فرزندان ارسال شود. به هر صورت باید دقت داشته باشیم که در هر دو حالت اگر منبع داده و یا محسابه تغییر کنند، در به روز رسانیها، توسط React بازتاب آن را خواهیم داشت. در مثال زیر کامپوننت DisplayAllInfos تشکیل شده از چهار کامپوننت دیگر است.
class DisplayAllInfos extends React.Component{ render(){ return ( <div classID="something" className="something"> <ProfilePhoto src={} /> <UserPersonalInfo userInfo={}/> <UserJobInfo jobInfo={}/> <UserContactInfo contactInfo={}/> </div> ) } }
حتی میشود تگ <div> در مثال بالا را بصورت یک کامپوننت درآورد و سایر کامپوننتها را به عنوان فرزند به آن کامپوننت معرفی کرد. روش کار به صورت زیر است.
class Container extends React.Component{ render(){ <div classID="something" className="something"> {this.props.children} </div> } } class DisplayAllInfos extends React.Component{ render(){ return ( <Container> <ProfilePhoto src={} /> <UserPersonalInfo userInfo={}/> <UserJobInfo jobInfo={}/> <UserContactInfo contactInfo={}/> </Container> ) } }
توسط خاصیت this.proprs.children در کامپوننت Container فرزندانی که برای این کامپوننت در نظر گرفته شده را نمایش میدهیم و به آنها دسترسی داریم.
روش دیگر فرزند خواندگی یک کامپوننت مالک، از طریق ایجاد آرایهای از کامپوننتهای فرزند است که در مثال نوشیدنیها آورده شد. این روش میتواند دچار اشکال شود. اگر عضوی از این آرایه حذف شود، یا اعضای آن درون آرایه تغییر مکان دهند و مسائلی از این دست که برای آرایهها پیش میآید، React قادر به تشخیص ترتیب فرزندها نیست و نمیتواند آنها را دوباره فراخوانی و ایجاد کند. برای رفع چنین مشکلی باید برای هر فرزندی که به یک مالک اضافه میکنیم، یک کلید در نظر بگیریم. از این پس وقتی آرایهای از فرزندها دچار تغییر شدند، React از روی کلیدهای منحصر به فرد آنها میتواند تغییرات را تشخیص داده و دوباره کامپوننت فرزند را به درستی بسازد. به مثال زیر توجه کنید.
var hotDrinks = [ {id: 1, item: "Tea", price: "7000" }, {id: 2, item: "Espresso", price: "10000" }, {id: 3, item: "Hot Chocolate", price: "12000" } ]; // {this.state.menuList.map(item => <MenuItem {...item} />)} var Menu = React.createClass({ render: function () { return ( <div className="row"> <div className="col-md-4"> <ul className="list-group"> {this.state.menuList.map(item => <MenuItem key={item.id} {...item} />)} </ul> </div> </div> ) } });
آن خط کدی که به صورت کامنت گذاشته شده همان روش قبل در مثال نوشیدنیهاست. در حالت اصلاح شده برای هر یک از MenuItemها یک id در نظر گرفته شده. باید توجه داشته باشیم که کلیدها حتما یگانه باشند و نکته دیگر اینکه این کلیدها فقط در زمان معرفی کامپوننت استفاده میشوند و نمیتوانیم داخل خود کامپوننت آنها را داشته باشیم. برای مثال در یک کامپوننت MenuItem مقدار this.props.key قابل استفاده نیست. هیچگاه از اندیس خود اعضای آرایه به عنوان کلید استفاده نکنید، چرا که با حذف یک مورد، در عمل وضعیت کلیدها را بهم ریختهاید و شاهد رفتاری غیرقابل پیشبینی خواهید شد.
در قسمت بعدی اعتبارسنجی را در کتابخانه React بررسی میکنیم.
- اگر از یک سیستم تزریق وابستگیها استفاده میکنید، مطلب جاری را فراموش کنید. یک کلاس معمولی را ایجاد کرده و یک اینترفیس را از آن استخراج کنید (مانند همیشه و بسیار عادی). سپس این اینترفیس و کلاس پیاده سازی کنندهی آنرا با «طول عمر» singleton به این IoC Container معرفی کنید (مهم نیست نام آن IoC Container چیست. این روش همه جا کار میکند). اکنون چون مدیریت طول عمر این سرویس توسط IoC container مورد استفاده کنترل میشود، میتوانید در سازندهی آن تمام سرویسهای دیگر را هم تزریق کرده (مانند تمام سرویسهای دیگر تعریف شده) و استفاده کنید؛ چون وهله سازی و مدیریت طول عمر آن توسط خود Container مدیریت میشود.
Install-Package Microsoft.AspNetCore.Mvc.Versioning
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddApiVersioning(); // ... }
services.AddApiVersioning(opt => { opt.AssumeDefaultVersionWhenUnspecified = true; opt.DefaultApiVersion = new ApiVersion(1, 0); });
- api/foo?api-version=1.0/
opt.DefaultApiVersion = new ApiVersion(new DateTime(2018, 10, 22));
- api/foo?api-version=2018-10-22/
URL Path Segment Versioning
[Route("api/v{version:apiVersion}/[controller]")] public class FooController : ControllerBase { public ActionResult<IEnumerable<string>> Get() { return new[] { "value1", "value2" }; } }
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddApiVersioning(opt => opt.ApiVersionReader = new HeaderApiVersionReader("api-version")); }
Deprecating
[ApiVersion("2")] [ApiVersion("1", Deprecated = true)] [Route("api/v{version:apiVersion}/[controller]")] public class FooController : ControllerBase { [HttpGet] public string Get() => "I'm deprecated, Bye bye :("; [HttpGet, MapToApiVersion("2.0")] public string GetV2() => "Hello world ! :D"; }
services.AddApiVersioning(opt => { opt.DefaultApiVersion = new ApiVersion(1, 0); opt.AssumeDefaultVersionWhenUnspecified = true; opt.ReportApiVersions = true; });
Ignoring Versioning
[ApiVersionNeutral] [Route("api/[controller]")] public class BarController : ControllerBase { public string Get() => HttpContext.GetRequestedApiVersion().ToString(); }
مطلب تکمیلی:
namespace TestVersioning.Controllers.V1 { [ApiVersion("1", Deprecated = true)] [Route("api/v{version:apiVersion}/[controller]")] public class FooController : ControllerBase { public string Get() => "I'm deprecated, Bye bye :("; } } namespace TestVersioning.Controllers.V2 { [ApiVersion("2")] [Route("api/v{version:apiVersion}/[controller]")] public class FooController : ControllerBase { public string GetV2() => "Hello world ! :D"; } }
معرفی Blazor Hybrid
- در Blazor Web Assembly که UI با HTML / CSS زده میشود، کدهای C# .NET ای با کمک Web Assembly و داخل خود مرورگر اجرا میشوند. با کمک Blazor Web Assembly میتوان محصولات PWA و SPA ایجاد نمود.
- در Blazor Server که UI با HTML / CSS زده میشود، کدها در سرور اجرا و به وسیلهی Web Sockets، تعاملات UI ای از Browser به سرور ارسال و تغییرات UI ای از سرور به Browser ارسال میشوند. با کمک Blazor Server میتوان محصولات SPA ایجاد نمود.
- Blazor Native Mobile Apps که در این روش از کامپوننتهای Native موبایل استفاده میشود؛ نه عناصر HTML مانند h1 و div. با کمک Blazor Native Mobile Apps میتوان برنامههای Native موبایل برای Android / iOS و برنامههای Desktop برای Windows ایجاد نمود.
- Blazor Hybrid که در این روش UI با HTML / CSS بوده، ولی اجرای کدهای C# .NET داخل خود سیستم عامل و به صورت Native است. با کمک Blazor Hybrid میتوان برنامههای موبایل برای Android / iOS و برنامههای Desktop برای Windows ایجاد نمود.
Bridge Network Driver
The bridge
networking driver is the first driver on our list. It’s simple to understand, simple to use, and simple to troubleshoot, which makes it a good networking choice for developers and those new to Docker. The bridge
driver creates a private network internal to the host so containers on this network can communicate. External access is granted by exposing ports to containers. Docker secures the network by managing rules that block connectivity between different Docker networks.
Overlay Network Driver
The built-in Docker overlay
network driver radically simplifies many of the complexities in multi-host networking. It is a swarm scope driver, which means that it operates across an entire Swarm or UCP cluster rather than individual hosts. With the overlay
driver, multi-host networks are first-class citizens inside Docker without external provisioning or components. IPAM, service discovery, multi-host connectivity, encryption, and load balancing are built right in. For control, the overlay
driver uses the encrypted Swarm control plane to manage large scale clusters at low convergence times.
MACVLAN Driver
The macvlan
driver is the newest built-in network driver and offers several unique characteristics. It’s a very lightweight driver, because rather than using any Linux bridging or port mapping, it connects container interfaces directly to host interfaces. Containers are addressed with routable IP addresses that are on the subnet of the external network.
As a result of routable IP addresses, containers communicate directly with resources that exist outside a Swarm cluster without the use of NAT and port mapping. This can aid in network visibility and troubleshooting. Additionally, the direct traffic path between containers and the host interface helps reduce latency. macvlan
is a local scope network driver which is configured per-host. As a result, there are stricter dependencies between MACVLAN and external networks, which is both a constraint and an advantage that is different from overlay
or bridge
.
docker run --rm -v $(pwd):$(pwd) -w $(pwd)\ jrottenberg/ffmpeg \ -f lavfi -i testsrc=size=1280x720 -t 60 -pix_fmt yuv420p testsrc.mp4