Tag: dependency injection

循环依赖树,是否合理

我想出了一些解决方案,我的IoC / DI容器( Castle Windsor )声称有一个循环依赖树。 这是真的。 但我不确定这个循环是否有害。 这或多或少是依赖树: WebAPI控制器取决于…… …… 服务A取决于…… ……工作单位取决于…… ……存储库取决于…… …域事件管理器(1)取决于很多…… …域事件处理程序,一个取决于…… …… 服务A (2) (1) 域事件管理器是一个通用类,旨在协调由相同或其他域监听的具体域事件并执行副操作。 (2)这是依赖循环发生的地方 我的域事件管理和处理是在考虑面向方面的编程时实现的,因此,虽然它是依赖树的一部分,但给定的域事件处理程序可能依赖于或不依赖于同一依赖树中的服务:我认为域事件处理程序,如额外的顶级依赖项 。 但最坏的情况已经发生了。 我的观点是,由于域事件是一个交叉概念,给定的处理程序应该能够注入任何服务,甚至是已经存在于给定操作流的依赖树中的某个服务。 目前,我已经在受影响的域事件处理程序中使用属性注入修复了该问题,但无论如何可能有替代整个解决方法。

Ninject:将父实例提供给正在解决的子项

我有这个类层次结构: public interface ISR { } public interface ICU { } public interface IFI { } public class CU : ICU { } public class SR : ISR { public SR(IFI fi) { FI = fi; } public IFI FI { get; set; } } public class FI : IFI { public FI(ISR sr, ICU […]

如何告诉Ninject为嵌套构造函数注入相同的实例?

我有一个Windows服务应用程序,我想在我的服务类中使用Ninject。 有一些服务类使用其他服务类,比如说“低级”或更通用的服务类。 每个服务通常都需要一个数据库访问存储库。 例如,我有一个IRepository接口,一个IServices1和一个IServices2接口。 后两者有Services1和Services2实现,两者都有一个IRepository类型的构造函数参数。 现在假设Services1的实现想要使用IServices2接口的一些方法,所以我将另一个构造函数参数添加到Services1,类型为IServices2。 现在,当我手动实例化Services1类时,我会这样做: var repo = new MyRepository(); // implementing IRepository var service1 = new Services1(repo, new Services2(repo)); 这样我就可以确保两个服务都可以使用相同的存储库(这对我来说是一个基本要求)。 如何使用Ninject为此scneario为我准备一个IServices1实例并使用正确的IRepository注入? 或者这种方法有任何重大设计错误吗? 我不是在MVC平台上,所以我没有这里的请求范围,我认为如果它是MVC我会做任务。

DryIOC容器配置用于属性注入

我已经搜索了一个简单的例子来说明如何配置DryIoc容器以简单地将依赖关系注入属性,就像它注入构造函数args一样。 鉴于以下工作示例…… 集装箱登记: public static void Register(HttpConfiguration config) { var c = new Container().WithWebApi(config); c.Register(Reuse.Singleton); c.Register(Reuse.Singleton); } 小部件服务: public class WidgetService : IWidgetService { private readonly IWidgetRepository _widgetRepository; public WidgetService(IWidgetRepository widgetRepository) { _widgetRepository = widgetRepository; } public IList GetWidgets() { return _widgetRepository.GetWidgets().ToList(); } } 小部件存储库: public class WidgetRepository : IWidgetRepository { private readonly IList _widgets; […]

EF的DbContext的单例范围

所以我目前正在使用一个使用Entity Framework的ASP.NET MVC Web应用程序,我也使用Ninject进行dependency injection。 所以基本上,目前,这是我用Ninject注册我的DbContext和服务的方式。 kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); kernel.Bind().To().InSingletonScope(); 我用InSingletonScope注册它们,这意味着它们只会被创建一次并在应用程序的整个生命周期中使用(至少我是如何理解的)。 控制器: private IAccountService _accountService; public MemberController(IAccountService accountService) { _accountService = accountService; } 但是,我深深感到这个单例范围会导致我的Web应用程序出现问题,特别是对于Entity Framework的上下文,因为它是单例。 我已经面临一个小问题,如果我使用SQL Management Studio手动更新数据库,我的Web应用程序的entity framework中的数据将不会更新,直到我重新启动应用程序(似乎是EF中的一些缓存机制)。 – 但是,如果我删除InSingletonScope ,我将从EF中随机获取错误,说: IEntityChangeTracker的多个实例不能引用实体对象 我理解为什么会发生这种情况,因为AccountService初始化的DbContext可能与RegionService不同。 但我不知道如何解决这个问题。 我对dependency injection的理解仍然非常有限,所以有人可以建议吗? – 编辑:我已经尝试过更换为InRequestScope以进行所有注射,但我仍然InRequestScope IEntityChangeTracker的多个实例不能引用实体对象 尝试从我的应用程序中的另一个服务插入具有相关对象(外键)的新实体时。 这意味着他们仍在使用不同的DbContext,发生了什么?! 最后编辑:好的我发现了问题,这是我的缓存机制缓存了以前的请求,导致所有后续请求的关系问题。

跨程序集和命名空间的dependency injection

我正在研究DI问题,我认为我理解其原因,但我需要一些建议来解决。 我已经构建了一个独立的程序集,它与Sql(称为程序集a)和另一个包含业务逻辑的程序集(称为程序集b)进行对话。 我在b程序集中为db类创建了一个接口。 由于接口不是db程序集的一部分,因此我不需要对db项目的任何引用,如果我想在运行时运行unit testing而不是程序集,我可以加载对db程序集或存根的引用需要知道另一个。 我可以在编译看起来像这样的业务逻辑库中编写代码:(假装a和b是各自程序集中的名称空间) a.IDatabaseClass db_class = (a.IDatabase)new b.Database(); 但是当我尝试运行它时,我得到一个无效的强制转换exception。 我认为它编译是因为接口完美匹配类,但在运行时失败,因为对象签名在Database类的inheritance链中没有看到IDatabase。 在c ++中,你可以随心所欲地抛出任何东西,但是c#对于构建对象指针有点严格。 即使该类具有所有正确的函数签名,它也会因为对象不匹配而爆炸。 现在我可以将db对象接口放在具有db对象的程序集中,但是业务逻辑需要对db程序集的引用。 此外,这只会产生复杂性,因为如果我在unit testing中编写存根db对象,我需要对我将在测试存根对象中使用的接口的db程序集的引用。 通过这样做,这似乎并没有解开耦合…… 我可以将所有接口放在第三个程序集中,该程序集是db程序集,业务逻辑和unit testing的父级。 这就是解决循环依赖问题的方法。 但是,这会将db程序集绑定到父程序集,并使其与其他项目一起使用的模块化程度要低得多。 我愿意接受有关如何设置每个组件以便它们独立运行并可用于DI的建议。 我想我可以将测试存根对象保存在与真实代码相同的程序集中,但这看起来很奇怪。 解决方案:以下回复中的一个回复说明我拍摄的内容基本上是接口的鸭子类型。 C#当前不支持duck typing,但我认为它可能是可能的,因为接口实现的行为方式类似于你可能称之为部分类指针的方式(或者更准确地说,是函数指针的集合)。 我的实验向我展示了其他情况,这就是原因。 因此,在Redmond将“更多野鸭”放入c#之前,看起来我们无法完全达到最终优雅的解耦组件。

container.RegisterWebApiControllers(GlobalConfiguration.Configuration)导致InvalidOperationException

在我的集成测试中,我使用的是我正在测试的Web API项目中构建的相同的SimpleInjector.Container。 但是这一行在组合根类中: container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 导致exception: System.TypeInitializationException : The type initializer for ‘MyProject.Api.Test.Integration.HttpClientFactory’ threw an exception. —- System.InvalidOperationException : This method cannot be called during the application’s pre-start initialization phase. Result StackTrace: at MyProject.Api.Test.Integration.HttpClientFactory.Create() at MyProject.Api.Test.Integration.Controllers.ProductControllerIntegrationTest.d__0.MoveNext() in d:\Projects\My\MyProject.Api.Test.Integration\Controllers\ProductControllerIntegrationTest.cs:line 26 —– Inner Stack Trace —– at System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled() at System.Web.Compilation.BuildManager.GetReferencedAssemblies() at System.Web.Http.WebHost.WebHostAssembliesResolver.System.Web.Http.Dispatcher.IAssembliesResolver.GetAssemblies() at System.Web.Http.Dispatcher.DefaultHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver) at System.Web.Http.WebHost.WebHostHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver) […]

构造函数注入和默认重载

假设我们有 public interface ITimestampProvider { DateTime GetTimestamp(); } 和一个消耗它的类 public class Timestamped { private ITimestampProvider _timestampProvider public Timestamped(ITimestampProvider timestampProvider) { // arg null check _timestampProvider = timestampProvider; } public DateTime Timestamp { get; private set; } public void Stamp() { this.Timestamp = _timestampProvider.GetTimestamp(); } } 和默认实现: public sealed class SystemTimestampProvider : ITimestampProvider { public DateTime […]

是否应该向dependency injection许多“级别”而不是需要它?

我正在使用SOLID原则编写C#ASP.NET MVC Web应用程序。 我编写了一个ViewModelService ,它依赖于AccountService和RepositoryService ,所以我在ViewModelServer注入了这两个服务。 PermissionService依赖于HttpContextBase ,以便使用GetOwinContext()来获取UserManager的实例。 控制器有一个需要使用的HttpContextBase实例 – 所以我似乎必须将HttpContextBase实例注入ViewModelService ,然后将其注入PermissionService 。 所以,就代码而言,我有: public ViewModelService public CategoryRepository(ApplicationDbContext context, IPermissionService permissionservice) public AccountService(HttpContextBase httpcontext, IPrincipal securityprincipal) 为了实例化ViewModelService ,我接着这样做: new ViewModelService( new CategoryRepository( new ApplicationDbContext(), new PermissionService( new AccountService(HttpContext, Thread.CurrentPrincipal), new UserPasswordRepository(new ApplicationDbContext()), new ApplicationSettingsService())), new PasswordRepository( new ApplicationDbContext(), new PermissionService( new AccountService(HttpContext, Thread.CurrentPrincipal), new UserPasswordRepository(new […]

并行处理的dependency injection

我正在尝试练习手动dependency injection(还没有框架)来删除我的代码中的紧耦合。 这只是为了练习 – 我没有考虑具体的实现。 到目前为止,简单的构造函数注入工作正常。 但是当一个类必须在并行循环中使用另一个类时,我无法解决如何解决创建紧耦合的问题。 例: public class Processor { private IWorker worker; public Processor(IWorker worker) { this.worker = worker; } public List DoStuff() { var list = new List(); for (int i = 0; i < 10; i++) { list.Add(worker.GetString()); } return list; } public List DoStuffInParallel() { var list = new […]