参考:
http://stackoverflow.com/questions/2538132/lazy-loading-with-ninject
方案一:
public class Module : NinjectModule { public override void Load() { Bind(typeof(Lazy<>)).ToMethod(ctx => GetType() .GetMethod("GetLazyProvider", BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(ctx.GenericArguments[0]) .Invoke(this, new object[] { ctx.Kernel })); } protected Lazy<T> GetLazyProvider<T>(IKernel kernel) { return new Lazy<T>(() => kernel.Get<T>()); } }
方案二:
Ninject Lazy Load
namespace LayzyLoadTest { [TestClass] public class UnitTest1 { private IKernel InitKernel() { Ninject.IKernel kernel = new Ninject.StandardKernel(new LazyBinding()); //kernel.Load<LazyBinding>(); kernel.Bind<IPerson>().To<Father>(); kernel.Bind<IVehicle>().To<Car>(); kernel.Bind<IPlace>().To<Road>().Named("comm"); kernel.Bind<IPlace>().To<LazyRoad>().Named("lazy"); return kernel; } [TestMethod] public void TestMethod1() { var comm = InitKernel().Get<IPlace>("comm"); comm.CurSpeed(); comm.ShowSpeed(); //Console.WriteLine("------------------------------------------------"); //var lazy = kernel.Get<IPlace>("lazy"); ////lazy.CurSpeed(); ////lazy.ShowSpeed(); }
[TestMethod] public void Lazy() { var lazy = InitKernel().Get<IPlace>("lazy"); lazy.CurSpeed(); Console.WriteLine("----over curspeed--------------------"); lazy.ShowSpeed(); } } }
namespace LayzyLoadTest.LayzyClasses
{
#region Persons
interface IPerson
{
int RunSpeed();
}
class Child : IPerson
{
public Child()
{
Console.WriteLine("Ctor Child");
}
public int RunSpeed()
{
Console.WriteLine("Child's Speed");
return 100;
}
}
class Father : IPerson
{
public Father()
{
Console.WriteLine("Ctor Father");
}
public int RunSpeed()
{
Console.WriteLine("Father's Speed");
return 1000;
}
}
interface IVehicle
{
int Improve();
}
class Car : IVehicle
{
public Car()
{
Console.WriteLine("Car's Ctor");
}
public int Improve()
{
Console.WriteLine("Car Improve");
return 1000;
}
}
class Bicycle : IVehicle
{
public Bicycle()
{
Console.WriteLine("Bicycle's Ctor");
}
public int Improve()
{
Console.WriteLine("Bicycle Improve");
return 100;
}
}
#endregion
#region Place
interface IPlace
{
int CurSpeed();
int ShowSpeed();
}
class Road : IPlace
{
private readonly IPerson _person;
private readonly IVehicle _vehicle;
public Road(IPerson person, IVehicle vehicle)
{
Console.WriteLine(" Road's Ctor ");
_person = person;
_vehicle = vehicle;
}
public int CurSpeed()
{
Console.WriteLine("Road CurSpeed");
return _person.RunSpeed();
}
public int ShowSpeed()
{
Console.WriteLine("Road ShowSpeed");
return _person.RunSpeed() * _vehicle.Improve();
}
}
class LazyRoad : IPlace
{
private readonly Lazy<IPerson> _person;
private readonly Lazy<IVehicle> _vehicle;
public LazyRoad(Lazy<IPerson> person, Lazy<IVehicle> vehicle)
{
Console.WriteLine(" LazyRoad's Ctor ");
_person = person;
_vehicle = vehicle;
}
public int CurSpeed()
{
Console.WriteLine("LazyRoad CurSpeed");
return _person.Value.RunSpeed();
}
public int ShowSpeed()
{
Console.WriteLine("LazyRoad ShowSpeed");
return _person.Value.RunSpeed() * _vehicle.Value.Improve();
}
}
#endregion
}
namespace LayzyLoadTest
{
public class LazyBinding : NinjectModule
{
public override void Load()
{
this.Bind(typeof(Lazy<>))
.ToMethod(
context =>
((ILazyLoader)Activator.CreateInstance(typeof(LazyLoader<>).MakeGenericType(context.GenericArguments),
new object[] { context.Kernel })).Loader);
}
public interface ILazyLoader
{
object Loader { get; }
}
public class LazyLoader<T> : ILazyLoader
{
private readonly IKernel _kernel;
private static readonly Func<IKernel, Lazy<T>> _lazyLoader = k => new Lazy<T>(() => k.Get<T>());
public LazyLoader(IKernel kernel)
{
if (kernel == null)
throw new ArgumentNullException("kernel");
this._kernel = kernel;
}
public object Loader { get { return _lazyLoader(this._kernel); } }
}
}
}