我正在ASP.NET MVC3应用程序中从StructureMap迁移到Simple Injector.
我正在使用控制器DI的MVC3扩展,但我遇到了尝试替换StructureMap的静态方面的问题.我们有电话
StructureMap.ObjectFactory.GetInstance<Interface>()
Run Code Online (Sandbox Code Playgroud)
在应用程序的不同层.它看起来不像Simple Injector有办法做到这一点.
我错过了什么吗?或者Simple Injector不适用于我的应用程序?
请提前告知并提前致谢.
我正在尝试使用Simple Injector(+ integration MVC)v 2.5.2.对于MVC 4应用程序,我也需要跟踪/记录性能(执行)(通过log4net模块).当前实现(在运行时)在指定的路径中创建log4net文件,但没有写入任何文本行(当我调试它时,一切都没有错误到_logger.Info("message")的结尾).
有没有人尝试使用Simple Injector DI for log4net?
我注册log4net模块的方式是:
public static class LoggingModule
{
public static void RegisterServices(Container container)
{
string log4NetConfigFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(log4NetConfigFile));
var logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
container.RegisterSingle(logger);
}
}
Run Code Online (Sandbox Code Playgroud)
并在Global.asax
LoggingModule.RegisterServices(container);
Run Code Online (Sandbox Code Playgroud)
Log4net配置文件看起来像这样(我不认为有任何问题):
<log4net>
<appender name="PerformanceLogFile" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="..\Performance\PricingManager" />
<param name="AppendToFile" value="true" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="_yyyy-MM-dd.lo\g" />
<param name="MaxSizeRollBackups" value="10" />
<param name="StaticLogFileName" value="false" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%m%n"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param …Run Code Online (Sandbox Code Playgroud) 假设我有两个控制器:ControllerA和ControllerB.这两个控制器都接受参数IFooInterface.现在我有2个IFooInterface,FooA和FooB的实现.我想在ControllerA中注入FooA,在ControllerB中注入FooB.这很容易在Ninject中实现,但由于性能更好,我正在转向Simple Injector.那么我怎样才能在Simple Injector中做到这一点?请注意,ControllerA和ControllerB驻留在不同的程序集中并动态加载.
谢谢
我正在尝试将SimpleInjector与WebFormsMvp结合起来.
为了方便DI WebFormsMvp提供了IPresenterFactory界面.
它包含Create提供要解析的演示者类型和视图实例的方法.
我需要注入的视图实例进入了一个构造的主持人.
演示者还具有需要由容器创建的其他依赖项.
这是我到目前为止所得到的,但它并不理想.这个问题
的正确解决方案是什么?
Presenter构造函数:
public FooPresenter(IFooView view, IClientFactory clientFactory) : base(view)
Run Code Online (Sandbox Code Playgroud)
厂:
public class SimpleInjectorPresenterFactory : IPresenterFactory
{
private readonly Container _container;
private IView _currentView;
public SimpleInjectorPresenterFactory()
{
_container = new Container();
Func<Type, bool> isIView =
type => typeof(IView).IsAssignableFrom(type);
_container.ResolveUnregisteredType += (s, e) => {
if …Run Code Online (Sandbox Code Playgroud) 我正在遵循史蒂文记录并使用Simple Injector 记录的一些实践.我有一个查询从WCF服务检索数据,我想使用的实例缓存结果.ObjectCache
我已经定义了一个装饰器CachingQueryHandlerDecorator<TQuery, TResult>:
public sealed class CachingQueryHandlerDecorator<TQuery, TResult>
: IQueryHandler<TQuery, TResult>
where TQuery : IQuery<TResult>
{
private readonly IQueryHandler<TQuery, TResult> _handler;
private readonly ObjectCache _cache;
private readonly CacheItemPolicy _policy;
private readonly ILog _log;
public CachingQueryHandlerDecorator(IQueryHandler<TQuery, TResult> handler,
ObjectCache cache,
CacheItemPolicy policy,
ILog log)
{
_handler = handler;
_cache = cache;
_policy = policy;
_log = log;
}
public TResult Handle(TQuery query)
{
var key = query.GetType().ToString();
var result = (TResult) _cache[key]; …Run Code Online (Sandbox Code Playgroud) 有RegisterPerWebRequest和RegisterWithContext(这一个最初并没有附带简单的喷射器,但是它在高级方案部分提供).另外两种方法都可以正常工作,但我需要将它们结合起来.
我发现在RegisterPerWebRequest使用过的new WebRequestLifestyle()生活方式中(在那里发现).所以不是使用Lifestyle.Transient RegisterWithContext我提供的,new WebRequestLifestyle()而是看起来DependencyContext.ImplementationType并且DependencyContext.ServiceType为空.
这有什么问题?
更新1.
因此,我希望像每个Web请求一样注册类型,RegisterPerWebRequest但也能够为实例创建者提供对注入注册类型的类型的访问权限.
我修改(提取生活方式作为参数)RegisterWithContext为:
public static void RegisterWithContext<TService>(
this Container container,
Func<DependencyContext, TService> contextBasedFactory, Lifestyle lifestyle)
where TService : class
{
//original code
container.Register<TService>(rootFactory, lifestyle);
//original code
}
Run Code Online (Sandbox Code Playgroud)
对于"每个Web请求和上下文"注册,我希望能够使用:
container.RegisterWithContext<IUnitOfWork>(dependencyContext =>
{
var implementationType = dependencyContext.ImplementationType;
//do some stuff and return preconfigured UnitOfWork
}, new WebRequestLifestyle());
Run Code Online (Sandbox Code Playgroud)
正如我已经提到dependencyContext.ImplementationType的那样NULL
我正在使用SimpleInjector …
我目前第一次使用Simple Injector.在我的.NET项目中,我正在运行测试和模拟从Web服务返回的数据并将对象注册到容器中
_container.Register<IWebServiceOrder>(() => mock.Object, Lifestyle.Transient);
Run Code Online (Sandbox Code Playgroud)
这很好用.但在我的测试中,我想在第二次调用包含更新数据的Web服务时测试系统的行为,因此需要更新模拟对象.
默认情况下,Simple Injector不允许覆盖现有注册,但官方网站声明可以更改此行为,如下所示.
https://simpleinjector.readthedocs.org/en/latest/howto.html#override-existing-registrations
container.Options.AllowOverridingRegistrations = true;
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我尝试第二次注册对象时,即使使用上面的代码,我仍然会收到错误.
首次调用GetInstance,GetAllInstances和Verify后,无法更改容器
有关为什么会发生这种情况的任何想法?
我正在用C#编写一个队列处理器作为Windows服务.后端队列机制是MongoDB.队列的目的是运行源自我们主网站(Angular w Web API)的带外请求.对于每个排队的项目,我想要一个序列化的Command实例+序列化的上下文信息
foreach请求周期:
1)如果当前命令处理程序需要它,则新建DbContext(EF)
2)反序列化AppContext并将该信息注入当前的命令处理程序
不知道如何在Simple Injector中处理这些模式.特别是因为这是Timer的循环,而不是已经为其编写过helper/classes的Web Request.思考?我见过其他IoC容器过去使用lambda表达式来处理这类东西.只是不确定如何处理我的#1和#2场景.
c# entity-framework ioc-container inversion-of-control simple-injector
我有以下(简化的)代码。
public class Controller
{
private readonly IService _service;
public Controller(IService service)
{
_service = service;
}
public async Task<IHttpActionResult> Create(MyObject object)
{
var result = _service.method(object);
if (!result.Succeeded)
{
return this.GetErrorResult(object);
}
}
}
Run Code Online (Sandbox Code Playgroud)
而 SimpleInjector 用于注入 _service 与其实现类之间的依赖关系,如下所示:
public static void Register(Container container)
{
container.Register<IService, Service>();
}
Run Code Online (Sandbox Code Playgroud)
请注意,注入和单元测试对我来说是新的,所以我不完全理解它们,但正在学习。
如果我通过 Swagger 运行应用程序,一切正常。
请注意,Register当我通过 Swagger 运行应用程序时会调用该函数。
现在,我正在尝试使用 NUnit 设置一些单元测试,并像这样模拟 IService 对象:
var Service = new Mock<IService>();
Controller _controller = new Controller(Service.Object);
_controller.Create(new MyObject object());
Run Code Online (Sandbox Code Playgroud)
到目前为止,这对我来说似乎是正确的 - 尽管我不确定?
问题是对于单元测试, …
随着.NET 4.7.2的更改,现在可以在Web窗体中进行构造函数注入.我已经使用简单注入器使用Web窗体,但是想要一些输入,如果有任何"陷阱"我可能会丢失.
首先,我有自己的网页是从拍摄的注册这里.
public static void RegisterWebPages(this Container container)
{
var pageTypes =
from assembly in BuildManager.GetReferencedAssemblies().Cast<Assembly>()
where !assembly.IsDynamic
where !assembly.GlobalAssemblyCache
from type in assembly.GetExportedTypes()
where type.IsSubclassOf(typeof(Page))
where !type.IsAbstract && !type.IsGenericType
select type;
foreach (Type type in pageTypes)
{
var reg = Lifestyle.Transient.CreateRegistration(type, container);
reg.SuppressDiagnosticWarning(
DiagnosticType.DisposableTransientComponent,
"ASP.NET creates and disposes page classes for us.");
container.AddRegistration(type, reg);
}
}
Run Code Online (Sandbox Code Playgroud)
当从上面的链接使用属性注入方法时,这很有效.我把它包括在这里是为了完整.
当我第一次连线时,有OutputCacheModule一个内部构造函数的问题.使用此处的代码,我能够解决该问题以及可能源自内部构造函数的任何其他问题.以下是该实现的完整性代码.
public class InternalConstructorResolutionBehavior : IConstructorResolutionBehavior
{
private IConstructorResolutionBehavior original;
public InternalConstructorResolutionBehavior(Container container)
{
this.original …Run Code Online (Sandbox Code Playgroud) simple-injector ×10
c# ×9
.net ×3
asp.net-mvc ×2
mocking ×1
moq ×1
nunit ×1
structuremap ×1
webforms ×1
webformsmvp ×1