یک نکته: اضافه شدن Ignore Circular References به دات نت 6
JsonSerializerOptions options = new() { ReferenceHandler = ReferenceHandler.IgnoreCycles, WriteIndented = true };
JsonSerializerOptions options = new() { ReferenceHandler = ReferenceHandler.IgnoreCycles, WriteIndented = true };
public interface ILogActionService { void Log(string data); } public class LogAttribute : ActionFilterAttribute { public ILogActionService LogActionService { get; set; } public override void OnActionExecuted(ActionExecutedContext filterContext) { LogActionService.Log("......data......"); base.OnActionExecuted(filterContext); } }
[Log] public ActionResult Index() {}
using StructureMap; using System.Collections.Generic; using System.Web.Mvc; namespace DI06.CustomFilters { public class StructureMapFilterProvider : FilterAttributeFilterProvider { private readonly IContainer _container; public StructureMapFilterProvider(IContainer container) { _container = container; } public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { var filters = base.GetFilters(controllerContext, actionDescriptor); foreach (var filter in filters) { _container.BuildUp(filter.Instance); yield return filter; } } } }
//Using the custom StructureMapFilterProvider var filterProvider = FilterProviders.Providers.Single(provider => provider is FilterAttributeFilterProvider); FilterProviders.Providers.Remove(filterProvider); FilterProviders.Providers.Add(SmObjectFactory.Container.GetInstance<StructureMapFilterProvider>());
namespace DI06.IocConfig { public static class SmObjectFactory { private static readonly Lazy<Container> _containerBuilder = new Lazy<Container>(defaultContainer, LazyThreadSafetyMode.ExecutionAndPublication); public static IContainer Container { get { return _containerBuilder.Value; } } private static Container defaultContainer() { return new Container(x => { x.For<ILogActionService>().Use<LogActionService>(); x.Policies.SetAllProperties(y => { y.OfType<ILogActionService>(); }); }); } } }
namespace SameInterfaceDifferentClasses.Services.Contracts { public interface IMessageService { void Send(string message); } }
public class EmailService : IMessageService { public void Send(string message) { // ... } } public class SmsService : IMessageService { public void Send(string message) { //todo: ... } }
public interface IUsersManagerService { void ValidateUserByEmail(int id); } public class UsersManagerService : IUsersManagerService { private readonly IMessageService _emailService; private readonly IMessageService _smsService; public UsersManagerService(IMessageService emailService, IMessageService smsService) { _emailService = emailService; _smsService = smsService; } public void ValidateUserByEmail(int id) { _emailService.Send("Validated."); } }
ioc.For<IMessageService>().Use<SmsService>(); ioc.For<IMessageService>().Use<EmailService>();
public static class SmObjectFactory { private static readonly Lazy<Container> _containerBuilder = new Lazy<Container>(defaultContainer, LazyThreadSafetyMode.ExecutionAndPublication); public static IContainer Container { get { return _containerBuilder.Value; } } private static Container defaultContainer() { return new Container(ioc => { // map same interface to different concrete classes ioc.For<IMessageService>().Use<SmsService>(); ioc.For<IMessageService>().Use<EmailService>(); ioc.For<IUsersManagerService>().Use<UsersManagerService>() .Ctor<IMessageService>("smsService").Is<SmsService>() .Ctor<IMessageService>("emailService").Is<EmailService>(); }); } }
var usersManagerService = SmObjectFactory.Container.GetInstance<IUsersManagerService>(); usersManagerService.ValidateUserByEmail(id: 1);
namespace WinFormsIoc.Services { public interface IEmailsService { void SendEmail(string from, string to, string title, string message); } } namespace WinFormsIoc.Services { public class EmailsService : IEmailsService { public void SendEmail(string from, string to, string title, string message) { //todo: ... } } }
public partial class Form2 : Form { private readonly IEmailsService _emailsService; public Form2(IEmailsService emailsService) { _emailsService = emailsService; InitializeComponent(); }
var form2 = new Form2(ObjectFactory.GetInstance<IEmailsService>()); form2.Show();
var form2 = ObjectFactory.GetInstance<Form2>(); form2.Show();
using System.Windows.Forms; namespace WinFormsIoc.IoC { public interface IFormFactory { T Create<T>() where T : Form; } } using System.Windows.Forms; using StructureMap; namespace WinFormsIoc.IoC { public class FormFactory : IFormFactory { public T Create<T>() where T : Form { return ObjectFactory.GetInstance<T>(); } } }
using System; using System.Windows.Forms; using WinFormsIoc.IoC; namespace WinFormsIoc { public partial class Form1 : Form { private readonly IFormFactory _formFactory; public Form1(IFormFactory formFactory) { _formFactory = formFactory; InitializeComponent(); } private void btnShowForm2_Click(object sender, EventArgs e) { var form2 = _formFactory.Create<Form2>(); form2.Show(); } } }
Application.Run(new Form1());
Application.Run(ObjectFactory.GetInstance<Form1>());
void Application_Start(object sender, EventArgs e) { try { // startup stuff } catch { HttpRuntime.UnloadAppDomain(); // سبب ری استارت برنامه و آغاز مجدد آن با درخواست بعدی میشود throw; } }
public interface IAuthentication { bool IsUserAuthenticated(string userName, string password); } public class AuthenticationService : IAuthentication { public bool IsUserAuthenticated(string userName, string password) { return userName == "Vahid" && password == "123"; } } public class LoginController { private readonly IAuthentication _authentication; public LoginController(IAuthentication authentication) { _authentication = authentication; } // ... }
public class LoginController { private readonly Func<string, string, bool> _authenticationStrategy; public LoginController(Func<string, string, bool> authenticationStrategy) { _authenticationStrategy = authenticationStrategy; } // ... }
public class TestViewModel { private readonly ITestService _testService; public TestViewModel(ITestService testService) //تزریق وابستگی در سازنده کلاس { _testService = testService; }
namespace DI07.Services { public interface ITestService { string Test(); } } namespace DI07.Services { public class TestService: ITestService { public string Test() { return "برای آزمایش"; } } }
namespace DI07.Core { public interface IViewModel // از این اینترفیس خالی برای یافتن و علامتگذاری ویوو مدلها استفاده میکنیم { } }
using DI07.Services; using DI07.Core; namespace DI07.ViewModels { public class TestViewModel : IViewModel // علامتگذاری ویوو مدل { private readonly ITestService _testService; public TestViewModel(ITestService testService) //تزریق وابستگی در سازنده کلاس { _testService = testService; } public string Data { get { return _testService.Test(); } } } }
using System.Windows; using DI07.Core; using DI07.Services; using StructureMap; namespace DI07 { public partial class App { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); ObjectFactory.Configure(cfg => { cfg.For<ITestService>().Use<TestService>(); cfg.Scan(scan => { scan.TheCallingAssembly(); // Add all types that implement IView into the container, // and name each specific type by the short type name. scan.AddAllTypesOf<IViewModel>().NameBy(type => type.Name); scan.WithDefaultConventions(); }); }); } } }
using System.Windows.Controls; using StructureMap; namespace DI07.Core { /// <summary> /// Stitches together a view and its view-model /// </summary> public static class ViewModelFactory { public static void WireUp(this ContentControl control) { var viewName = control.GetType().Name; var viewModelName = string.Concat(viewName, "Model"); //قرار داد نامگذاری ما است control.Loaded += (s, e) => { control.DataContext = ObjectFactory.GetNamedInstance<IViewModel>(viewModelName); }; } } }
<UserControl x:Class="DI07.Views.TestView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <TextBlock Text="{Binding Data}" /> </Grid> </UserControl> <Window x:Class="DI07.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Views="clr-namespace:DI07.Views" Title="MainWindow" Height="350" Width="525"> <Grid> <Views:TestView /> </Grid> </Window>
using DI07.Core; namespace DI07.Views { public partial class TestView { public TestView() { InitializeComponent(); this.WireUp(); //تزریق خودکار وابستگیها و یافتن ویوو مدل متناظر } } }
using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Web.Mvc; namespace DI06.Controllers { public class HomeController : Controller { public ActionResult Index() { string result = string.Empty; using (var client = new WebClient { Encoding = Encoding.UTF8 }) { result = client.DownloadString("https://www.dntips.ir/"); } var match = new Regex(@"(?s)<title>(.+?)</title>", RegexOptions.IgnoreCase).Match(result); var title = match.Groups[1].Value.Trim(); ViewBag.PageTitle = title; return View(); } } }
namespace DI06.Services { public interface IWebClientServices { string FetchUrl(string url); string GetWebPageTitle(string url); } } using System.Net; using System.Text; using System.Text.RegularExpressions; namespace DI06.Services { public class WebClientServices : IWebClientServices { public string FetchUrl(string url) { using (var client = new WebClient { Encoding = Encoding.UTF8 }) { return client.DownloadString(url); } } public string GetWebPageTitle(string url) { var html = FetchUrl(url); var match = new Regex(@"(?s)<title>(.+?)</title>", RegexOptions.IgnoreCase).Match(html); return match.Groups[1].Value.Trim(); } } }
using System.Web.Mvc; using DI06.Services; namespace DI06.Controllers { public class HomeController : Controller { readonly IWebClientServices _webClientServices; public HomeController(IWebClientServices webClientServices) { _webClientServices = webClientServices; } public ActionResult Index() { ViewBag.PageTitle = _webClientServices.GetWebPageTitle("https://www.dntips.ir/"); return View(); } } }
PM> Install-Package structuremap
namespace DI03.Services { public interface IUsersService { string GetUserEmail(int userId); } } namespace DI03.Services { public interface IEmailsService { void SendEmailToUser(int userId, string subject, string body); } } using System; namespace DI03.Services { public class UsersService : IUsersService { public UsersService() { //هدف صرفا نمایش وهله سازی خودکار این وابستگی است Console.WriteLine("UsersService ctor."); } public string GetUserEmail(int userId) { //برای مثال دریافت از بانک اطلاعاتی و بازگشت یک نمونه جهت آزمایش برنامه return "name@site.com"; } } } using System; namespace DI03.Services { public class EmailsService: IEmailsService { private readonly IUsersService _usersService; public EmailsService(IUsersService usersService) { Console.WriteLine("EmailsService ctor."); _usersService = usersService; } public void SendEmailToUser(int userId, string subject, string body) { var email = _usersService.GetUserEmail(userId); Console.WriteLine("SendEmailTo({0})", email); } } }
using DI03.Services; using StructureMap; namespace DI03 { class Program { static void Main(string[] args) { // تنظیمات اولیه برنامه که فقط یکبار باید در طول عمر برنامه انجام شود ObjectFactory.Initialize(x => { x.For<IEmailsService>().Use<EmailsService>(); x.For<IUsersService>().Use<UsersService>(); }); //نمونهای از نحوه استفاده از تزریق وابستگیهای خودکار var emailsService = ObjectFactory.GetInstance<IEmailsService>(); emailsService.SendEmailToUser(userId: 1, subject: "Test", body: "Hello!"); } } }
UsersService ctor. EmailsService ctor. SendEmailTo(name@site.com)
using System; namespace DI03.Services { public class UsersService : IUsersService { private int _i; public UsersService() { //هدف صرفا نمایش وهله سازی خودکار این وابستگی است Console.WriteLine("UsersService ctor."); } public string GetUserEmail(int userId) { _i++; Console.WriteLine("i:{0}", _i); //برای مثال دریافت از بانک اطلاعاتی و بازگشت یک نمونه جهت آزمایش برنامه return "name@site.com"; } } }
//نمونهای از نحوه استفاده از تزریق وابستگیهای خودکار var emailsService1 = ObjectFactory.GetInstance<IEmailsService>(); emailsService1.SendEmailToUser(userId: 1, subject: "Test1", body: "Hello!"); var emailsService2 = ObjectFactory.GetInstance<IEmailsService>(); emailsService2.SendEmailToUser(userId: 1, subject: "Test2", body: "Hello!");
UsersService ctor. EmailsService ctor. i:1 SendEmailTo(name@site.com) UsersService ctor. EmailsService ctor. i:1 SendEmailTo(name@site.com)
// تنظیمات اولیه برنامه که فقط یکبار باید در طول عمر برنامه انجام شود ObjectFactory.Initialize(x => { x.For<IEmailsService>().Use<EmailsService>(); x.For<IUsersService>().Singleton().Use<UsersService>(); });
UsersService ctor. EmailsService ctor. i:1 SendEmailTo(name@site.com) EmailsService ctor. i:2 SendEmailTo(name@site.com)
Singleton() HttpContextScoped() HybridHttpOrThreadLocalScoped()
protected void Application_EndRequest(object sender, EventArgs e) { ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects(); }
// تنظیمات اولیه برنامه که فقط یکبار باید در طول عمر برنامه انجام شود ObjectFactory.Initialize(x => { //x.For<IEmailsService>().Use<EmailsService>(); //x.For<IUsersService>().Singleton().Use<UsersService>(); x.Scan(scan => { scan.AssemblyContainingType<IEmailsService>(); scan.WithDefaultConventions(); }); });