我有一个配置对象,我存储在数据库中.当应用程序启动时,我想从数据库重新构建对象,然后让Ninject控制它的生命周期.例如"InSingletonScope",当另一个对象请求此对象时,它将来自Ninject内核.
就像是:
Bind(myInstance).ToSelf().InSingletonScope();
Run Code Online (Sandbox Code Playgroud) 我有一个MVC3应用程序,我希望将服务于大量的用户请求.我想使用IoC容器,但不希望它降低我的应用程序的性能.
我读到我不应该担心,因为唯一的开销是在初始化时.但是对于MVC3应用程序,这不是用户每次请求新网页时吗?
我想做一些类似的事情:
kernel.Bind<IBootTaskA>().To<BootTaskA>().InSingletonScope();
kernel.Bind<IBootTaskB>().To<BootTaskB>().InSingletonScope();
kernel.Bind<IBootTask>().To<IBootTaskA>();
kernel.Bind<IBootTask>().To<IBootTaskB>();
Run Code Online (Sandbox Code Playgroud)
所以我可以这样做:
public class Boot
{
public Boot(IBootTask[] bootTasks)
{
foreach(var task in bootTasks){task.Execute();}
}
}
Run Code Online (Sandbox Code Playgroud)
但我似乎无法将接口绑定到接口,有人知道解决方法吗?
我是MVC和Ninject的新手.....使用Ninject我的Global.asax Application_start()中有这样的东西
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
Run Code Online (Sandbox Code Playgroud)
在NinjectControllerFactory类我有类似的东西
ninjectKernel.Bind<IDbFactory>().To<DbFactory>().InRequestScope(); <-- DBFactory!
ninjectKernel.Bind<IUnitOfWork>().To<UnitOfWork>(); <-- UnitOfwork!
ninjectKernel.Bind<IOrderService>().To<OrderService>(); <-- Service!
ninjectKernel.Bind<IRepository<Order>>().To<Repository<Order>>(); <-- Entities!
Run Code Online (Sandbox Code Playgroud)
好吧,我完全不喜欢它!
我不想在UI中引用我的数据层和EF层...我想只引用服务层,然后使用DTO将数据传入和传出我的UI ...
我创建了我的服务实例注入存储库...例如......
public OrderService(IRepository<Order> OrderRepository)
Run Code Online (Sandbox Code Playgroud)
我感到困惑和沮丧.有没有办法在我的UI中初始化ninject?
提前致谢!!!
JDBO
我正在测试Ninject并试图了解如何将存储库注入到单例类中.下面是工作存储库和单例类示例...
public interface ITestRepository
{
void TestRepositoryMethod();
}
public class TestRepository:ITestRepository
{
public void TestRepositoryMethod()
{
}
}
public class TestSingletonInjectionClass
{
private readonly ITestRepository _repository;
public TestSingletonInjectionClass(
ITestRepository repository)
{
_repository = repository;
}
public void TestMethod()
{
}
}
Run Code Online (Sandbox Code Playgroud)
通过成功的测试方法
[TestMethod]
public void SimpleTestSingleton()
{
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<ITestRepository>().To<TestRepository>();
var testSingletonInjectionClass =
kernel.Get<TestSingletonInjectionClass>();\
Assert.IsNotNull(testSingletonInjectionClass);
}
}
Run Code Online (Sandbox Code Playgroud)
我有两个问题
1.这是获取单例类实例的正确方法吗?
kernel.Get<TestSingletonInjectionClass>()
Run Code Online (Sandbox Code Playgroud)
2.如何从应用程序代码中获取单例实例类.在测试方法中,我创建Ninject内核并访问Get方法.如何访问ninject内核表单代码?
我刚刚开始在一个(大型)项目中使用Ninject,并且只是使用DI来启动它的一部分.我有一个使用构造函数注入广泛组织的子系统.使用Ninject注入这个子系统中的类之间的所有依赖关系是很好的.但是,我依赖于子系统之外的东西,我真的想使用Ninject自动注入,但不要负责它们的生命周期.
我认为Bind<T>.ToConstant(...)这对我想做的事情有用.例如,我可能有一个类型的Monkey类作为Singleton,但我的应用程序的另一部分是在没有Ninject的情况下处理它的生命周期(例如,创建它并手动处理它).当我的Ninject配备子系统被创建时,我实例化一个内核,绑定我的子系统类,然后使用类似Bind<Monkey>.ToConstant(Monkey.Instance)绑定到各种"外部"依赖项的东西.这在激活时工作得很好但在我处理内核时不能按需工作.我的子系统可以比这些外部依赖项具有更短的生命周期,但是当我在内核上调用Dispose时,所有这些依赖项都会被释放,这不是我想要的.虽然我可以通过两种方式看到参数,但是Ninject会自动处理它没有创建的对象似乎有点可疑.我希望至少有一种方法可以选择退出这种行为,但到目前为止我还没有发现任何东西.这有什么支持吗?
我真的很困惑小的,部分的,单文件的例子,其中有一个Ninject内核到处都没有显示如何真正到达应用程序中的内核.
(1)我们应该实例化一个内核并将其保存在"静态"上下文中吗?或者我们应该在每个请求上实例化一个不同的(*在Application_BeginRequest*中)
(2)如果它是"每个请求的内核",那么为什么在Application_Start上调用NinjectWebCommon.cs的Initialize()方法(在安装NuGet包时得到),因为它调用了bootstrapper.Initialize(CreateKernel) - NinjectWebCommon.cs
(3)如果它是"一个全局静态内核",则"InRequestScope()"不起作用.它执行以下代码并返回null,因为在ApplicationStart()时没有请求.
kernel.Components.GetAll<INinjectHttpApplicationPlugin>()
.Select(c => c.RequestScope)
.FirstOrDefault(s => s != null);
Run Code Online (Sandbox Code Playgroud)
(4)同样,如果它是"每个请求的内核",我们将在哪里保存内核?HttpContext.Current?那么如果我打算使用HttpContext.Current,那么使用InRequestScope()是什么意思呢?
我正在使用Ninject和AOP来做一些缓存.我有一个属性,我可以应用于我的存储库中的任何方法和BeforeInvoke它将返回我的缓存对象,如果有一个和AfterInvoke创建一个缓存的对象.这一切都很好,但我无法弄清楚如何停止调用初始方法,即如果有一个缓存的对象返回而不是调用intyercepted方法.我的拦截器在这里:
public class CacheInterceptor : SimpleInterceptor
{
protected override void BeforeInvoke(IInvocation invocation)
{
Type returnType = invocation.Request.Method.ReturnType;
string cacheKey = CacheKeyBuilder.GetCacheKey(invocation, serializer);
object cachedValue = cache.Get(cacheKey);
if (cachedValue == null)
{
invocation.Proceed();
}
else
{
object returnValue = serializer.Deserialize(returnType, cachedValue);
invocation.ReturnValue = returnValue;
returnedCachedResult = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
即使在else语句中我显然没有说要调用被调用的方法'invocation.Proceed();' 它仍然会调用它.如何告诉ninject只返回invocation.ReturnValue?
我正在尝试使用Ninject自动注册AutoMapper配置文件.为此,我需要实例化从AutoMapper.Profile继承的类型的对象,例如:
public class WordMapping : Profile
{
protected override void Configure()
{
Mapper.CreateMap<Datacontext.Entities.Word, Domain.Entities.Word>();
Mapper.CreateMap<Domain.Entities.Word, Datacontext.Entities.Word>();
}
}
Run Code Online (Sandbox Code Playgroud)
首先,我试图通过反射来做到这一点,它就像一个魅力:
var profileType = typeof(AutoMapper.Profile);
var profiles = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => profileType.IsAssignableFrom(t) && t.GetConstructor(Type.EmptyTypes) != null)
.Select(Activator.CreateInstance)
.Cast<Profile>();
foreach (var profile in profiles)
{
Mapper.AddProfile(profile);
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试用Ninject做同样的事情时:
public class MappingModules : NinjectModule
{
public override void Load()
{
Kernel.Bind(scanner =>
{
scanner.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom<AutoMapper.Profile>();
});
var profiles = Kernel.GetAll<Profile>();
foreach (var profile in profiles)
{
Mapper.AddProfile(profile);
}
}
} …Run Code Online (Sandbox Code Playgroud) 我有一个托管在我的本地IIS(而不是Express)上的WCF Web服务.我在其根目录中包含了一个Global.asax,它应该在那里.由于我使用Ninject与WCF扩展,类全球扩展,而不是一个HttpApplication NinjectHttpApplication(如看到这里).另外,我正在使用AutoMapper库来规避编写无聊的样板代码.出现这个问题的原因是我没有调用我为配置AutoMapper定义的静态方法,导致AutoMapper在调用Mapper.Map()时抛出异常.静态方法的调用是在Global.asax的Application_Start()方法中定义的,因为我希望每个Web服务的生命周期执行一次这些映射.顺便说一句,Ninject的CreateKernel()方法被调用就好了.我在这里错过了什么吗?我已经尝试过调试它,即使我已经将调试器附加到w3wp.exe并尝试在其正文中调用一个显式的Debugger.Break()调试,它也没有达到断点.
到目前为止它是这样的:
Global.asax中
<%@ Application Codebehind="Global.asax.cs" Inherits="MyApp.WebHost.Global" Language="C#" %>
Run Code Online (Sandbox Code Playgroud)
的Global.asax.cs
public class Global : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel();
/* various bindings */
return kernel;
}
protected void Application_Start(object sender, EventArgs e)
{
AutoMapperConfig.RegisterMappings();
}
/* rest of Global.asax methods (Session_Start, Application_BeginRequest, etc.) with empty bodies */
Run Code Online (Sandbox Code Playgroud)
RegisterMappings方法
public static class AutoMapperConfig
{
public static void RegisterMappings()
{
/* multiple calls to Mapper.CreateMap() */
Mapper.AssertConfigurationIsValid();
}
}
Run Code Online (Sandbox Code Playgroud)
Svc文件标记
<%@ …Run Code Online (Sandbox Code Playgroud) ninject ×10
c# ×5
.net ×2
asp.net-mvc ×2
automapper ×2
aop ×1
asp.net ×1
autofac ×1
binding ×1
castle ×1
dto ×1
global-asax ×1
interception ×1
ninject-2 ×1
reflection ×1
wcf ×1