public interface IWeapon { void Kill(); } public class Bazuka : IWeapon { public void Kill() { Console.WriteLine("BIG BADABUM!"); } } public class Sword : IWeapon { public void Kill() { Console.WriteLine("Chuk-chuck"); } } public class Warrior { readonly IWeapon Weapon; public Warrior(IWeapon weapon) { this.Weapon = weapon; } public void Kill() { Weapon.Kill(); } }
class Program { static void Main(string[] args) { Warrior warrior = new Warrior(new Bazuka()); warrior.Kill(); Console.ReadLine(); } }
BIG BADABUM!
Weapon.Kill();
Install-Package Ninject
public class WeaponNinjectModule : NinjectModule { public override void Load() { this.Bind<IWeapon>().To<Sword>(); } }
class Program { public static IKernel AppKernel; static void Main(string[] args) { AppKernel = new StandardKernel(new WeaponNinjectModule()); var warrior = AppKernel.Get<Warrior>(); warrior.Kill(); Console.ReadLine(); } }
AppKernel.Get<>()
. When creating AppKernel, we pass the module responsible for issuing weapons (in this case, the sword) as a constructor. Any object that we are trying to get via AppKernel.Get
will (if possible) be initialized if there are modules that know how to do it.Warrior
object does not take a weapon with it every time, and if it is not detected, it calls on the service to the locator and gets it: public class OtherWarrior { private IWeapon _weapon; public IWeapon Weapon { get { if (_weapon == null) { _weapon = Program.AppKernel.Get<IWeapon>(); } return _weapon; } } public void Kill() { Weapon.Kill(); } }
var otherWarrior = new OtherWarrior(); otherWarrior.Kill();
public property
) is marked with [Inject]
, then when creating a class via AppKernel.Get<>()
, the field is initialized by the locator service: public class AnotherWarrior { [Inject] public IWeapon Weapon { get; set; } public void Kill() { Weapon.Kill(); } } var anotherWarrior = AppKernel.Get<AnotherWarrior>(); anotherWarrior.Kill();
Install-Package Unity
Container = new UnityContainer();
Container.RegisterType(typeof(IWeapon), typeof(Bazuka));
var warrior = Container.Resolve<Warrior>(); warrior.Kill();
(Singleton) ServiceLocator
, which registers the container and allows you to access services from anywhere. var serviceProvider = new UnityServiceLocator(Container); ServiceLocator.SetLocatorProvider(() => serviceProvider);
OtherWarrior
now gets a weapon like this: public class OtherWarrior { private IWeapon _weapon; public IWeapon Weapon { get { if (_weapon == null) { _weapon = ServiceLocator.Current.GetInstance<IWeapon>(); } return _weapon; } } public void Kill() { Weapon.Kill(); } }
Install-Package Autofac
ContainerBuilder
) - no, no, this is not the container itself, it is like modules var builder = new ContainerBuilder();
builder.RegisterType<Bazuka>(); builder.RegisterType<Warrior>(); builder.Register<IWeapon>(x => x.Resolve<Bazuka>());
var container = builder.Build();
var warrior = container.Resolve<Warrior>(); warrior.Kill();
Install-Package Castle.Windsor
var container = new WindsorContainer();
container.Register(Component.For<IWeapon>().ImplementedBy<Bazuka>(), Component.For<Warrior>().ImplementedBy<Warrior>());
var warrior = container.Resolve<Warrior>(); warrior.Kill();
Web.config (App.config)
files. Some set the rules for initialization, as we now look at the Ninject extension for asp.net mvc - this concerns the initialization of the service locator as a shared object generator, and separately for each stream or web request.Region | Binding method | Explanation |
Temporary | .InTransientScope() | The class object will be created upon each request (default method). |
Single mother | .InSingletonScope() | The class object will be created once and will be reused. |
Flow | .InThreadScope() | One object per stream. |
Request | .InRequestScope() | One object will be for each web request |
_container.RegisterType<DbContext, SavecashTravelContext>(new PerRequestLifetimeManager());
public class PerRequestLifetimeManager : LifetimeManager { /// <summary> /// Key to store data /// </summary> private readonly string _key = String.Format("SingletonPerRequest{0}", Guid.NewGuid()); /// <summary> /// Retrieve a value from the backing store associated with this Lifetime policy. /// </summary> /// <returns> /// the object desired, or null if no such object is currently stored. /// </returns> public override object GetValue() { if (HttpContext.Current != null && HttpContext.Current.Items.Contains(_key)) return HttpContext.Current.Items[_key]; return null; } /// <summary> /// Stores the given value into backing store for retrieval later. /// </summary> /// <param name="newValue">The object being stored.</param> public override void SetValue(object newValue) { if (HttpContext.Current != null) HttpContext.Current.Items[_key] = newValue; } /// <summary> /// Remove the given object from backing store. /// </summary> public override void RemoveValue() { if (HttpContext.Current != null && HttpContext.Current.Items.Contains(_key)) HttpContext.Current.Items.Remove(_key); } }
HttpContext.Current.Items[_key]
and are issued only if they are already in the same context ( HttpContext.Current
). Otherwise, a new object is created. If the current context ( HttpContext.Current
) in the code area does not exist (we use such LifetimeManager
in the console application or in a separate thread), then this container will not work. public class HomeController : Controller { public ActionResult Index() { return View(); } }
@{ ViewBag.Title = "LessonProject"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>LessonProject</h2>
Install-Package Ninject.MVC3
[assembly: WebActivator.PreApplicationStartMethod(typeof(LessonProject.App_Start.NinjectWebCommon), "Start")] [assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(LessonProject.App_Start.NinjectWebCommon), "Stop")] namespace LessonProject.App_Start { using System; using System.Web; using Microsoft.Web.Infrastructure.DynamicModuleHelper; using Ninject; using Ninject.Web.Common; public static class NinjectWebCommon { private static readonly Bootstrapper bootstrapper = new Bootstrapper(); /// <summary> /// Starts the application /// </summary> public static void Start() { DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); bootstrapper.Initialize(CreateKernel); } /// <summary> /// Stops the application. /// </summary> public static void Stop() { bootstrapper.ShutDown(); } /// <summary> /// Creates the kernel that will manage your application. /// </summary> /// <returns>The created kernel.</returns> private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); RegisterServices(kernel); return kernel; } /// <summary> /// Load your modules or register your services here! /// </summary> /// <param name="kernel">The kernel.</param> private static void RegisterServices(IKernel kernel) { } } }
public interface IWeapon { string Kill(); } … public class Bazuka : IWeapon { public string Kill() { return "BIG BADABUM!"; } } … private static void RegisterServices(IKernel kernel) { kernel.Bind<IWeapon>().To<Bazuka>(); }
[Inject]
: public class HomeController : Controller { [Inject] public IWeapon weapon { get; set; } public ActionResult Index() { return View(weapon); } }
@model LessonProject.Models.IWeapon @{ ViewBag.Title = "LessonProject"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>LessonProject</h2> <p> @Model.Kill() </p>
public class HomeController : Controller { private IWeapon weapon { get; set; } public HomeController() { weapon = DependencyResolver.Current.GetService<IWeapon>(); } public ActionResult Index() { return View(weapon); } }
Source: https://habr.com/ru/post/176007/
All Articles