我似乎需要这么多.
假设我有一个带有构造函数的类,它带有几个参数.其中一些可以通过注册组件来解决.但其余的是在运行时创建的实例(例如,从数据库中获取实体).
Autofac能以一种很好的方式处理这些情况吗?或者我的设计是次优的?
为了澄清,我有类这样的构造函数的类:
public MyClass(IService1 service1, IService2 service2, Data1 data1, Data2 data2)
{
//...
}
Run Code Online (Sandbox Code Playgroud)
我想做这样的事情:
container.Resolve<MyClass>(data1, data2);
在我的服务层上,我UnitOfWork在构造函数中注入了一个和两个存储库.工作单元和存储库有一个DbContext我想在两者之间共享的实例.我怎么能用Ninject做到这一点?应考虑哪个范围?
我不在网络应用程序中,所以我无法使用InRequestScope.
我尝试做类似的事情......然而我正在使用DI,我需要我的UoW Dispose并且像这样创建.
using (IUnitOfWork uow = new UnitOfWorkFactory.Create())
{
_testARepository.Insert(a);
_testBRepository.Insert(b);
uow.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
编辑:我只是想确定我理解...看看https://github.com/ninject/ninject.extensions.namedscope/wiki/InNamedScope我虽然关于我当前使用Ninject的控制台应用程序架构.
让我们说:
A类是服务层类
B类是一个工作单元,它接受参数接口(IContextFactory)
C类是一个接口参数的存储库(IContextFactory)
这里的想法是能够在2个或更多存储库上执行上下文操作,并使用工作单元来应用更改.
D类是一个上下文工厂(实体框架),它提供了一个实例(保存在容器中)的上下文,它在Class B et C之间共享(并且将用于其他存储库).
上下文工厂将实例保存在他的容器中,所以我不想重复使用这个实例的所有名称,因为上下文需要在服务操作结束时处理..实际上InNamedScope的主要目的是什么?
解决方案是,但我不确定我做得对,服务实例将是transcient,这意味着他们实际上从未处理过?:
Bind<IScsContextFactory>()
.To<ScsContextFactory>()
.InNamedScope("ServiceScope")
.WithConstructorArgument(
"connectionString",
ConfigurationUtility.GetConnectionString());
Bind<IUnitOfWork>().To<ScsUnitOfWork>();
Bind<IAccountRepository>().To<AccountRepository>();
Bind<IBlockedIpRepository>().To<BlockedIpRepository>();
Bind<IAccountService>().To<AccountService>().DefinesNamedScope("ServiceScope");
Bind<IBlockedIpService>().To<BlockedIpService>().DefinesNamedScope("ServiceScope");
Run Code Online (Sandbox Code Playgroud) UPDATE
发现这个小宝石帮助我使用DbContext Josh Kodroff - 让实体框架更加单元可测试
原版的
经过大量的研究后,我终于决定在我的MVC5 EF6项目中使用Autofac实现IOC.Autofac的文档很有用,但我仍然不确定是否需要在Controller或Service Class中调用Dispose()?
我没有使用抽象的UOW和Generic Repository,只是依赖于EF6中提供的DbContext和DbSet <>.这是我课程的片段.
我的DbContext
public class ProductContext : DbContext
{
public ProductContext() : base("ProductContext")
{
}
public DbSet<Availability> Availability { get; set; }
public DbSet<Category> Categories { get; set; }
....
}
Run Code Online (Sandbox Code Playgroud)
我的服务类
public class ProductService : IProductService
{
private ProductContext _db;
public ProductService(ProductContext db)
{
_db = db;
}
public List<Product> GetProductsByCategory(string cleanCategory)
{
return _db.Products
.Include(p => p.Options.Select(o => o.OptionGroup))
.Include(p => p.Associations.Select(a => a.AssociatedGroup))
.Include(p => p.Variations).Include(p …Run Code Online (Sandbox Code Playgroud) 我的存储库中抛出了一系列非常奇怪的错误.未找到或更改行,2个更新中的1个失败...没有任何意义.
好像我的DataContext实例正在被缓存......没有任何意义,我正在考虑职业生涯.
然后我注意到使用Ninject使用依赖注入传递了DataContext实例(这是我第一次使用DI ...).我撕掉了依赖注入,一切都恢复了正常.即刻.
所以依赖注入是个问题,但我仍然不知道为什么.我猜测Ninject正在缓存注入的DataContext.
它是否正确?
Ninject绑定如下:
Bind<IPupilBlockService>().To<SqlPupilBlockService>()
.WithConstructorArgument("db", new dbDataContext());
Run Code Online (Sandbox Code Playgroud) 我有几个基于System.Entity.Data.DbContext的类.它们在Web应用程序的不同端部被多次使用请求 - 实例化它们是否昂贵?
我在HttpContext.Current.Items中缓存了它们的副本,因为每个请求都有几个副本它们感觉不对,但我现在发现它不会自动从HttpContext处理掉.请求.在我开始编写代码来处理它之前(在Application_EndRequest中),我认为我已经重新考虑了这种情况,因为如果我应该在需要它们的地方实例化它们并在那里处理它们,那么实际上没有必要缓存它们.
互联网上已经提出了与此类似的问题,但我似乎无法找到一个完全回答我的问题的问题.对不起,如果我正在重复某人.
更新
我发现在这篇博客文章中处理上下文可能并不重要,但我仍然有兴趣听到它们首先实例化是否昂贵.基本上,幕后有很多EF魔法,我想避免经常这么做吗?
我在MVC 3 Web应用程序中使用Simple Injector作为IOC.我正在使用RavenDB进行数据存储.在mvc 3应用程序中使用RavenDB有几个注意事项.我搜索了一些关于如何连接IoC以使用RavenDB,但还没有找到如何连接简单的注入器来使用RavenDB.任何人都可以解释如何连接简单的注入器在MVC 3 Web应用程序中使用RavenDB?
谢谢.
.net inversion-of-control ravendb asp.net-mvc-3 simple-injector
考虑一个ASP.NET Web API 2应用程序,它使用Entity Framework提供对几个数据库表的相当直接的访问.
在为大多数并发请求提供服务方面,对象生命周期的以下哪个选项最佳?
后续问题 - 如果我将要求更改为"需要最少量的DB服务器资源"该怎么办?什么是最好的选择?
我有一个 ASP.NET MVC 项目,它使用实体框架、SignalR 和 Hangfire 作业。
我的主(根)容器是这样定义的:
builder.RegisterType<DbContext>().InstancePerLifetimeScope(); // EF Db Context
builder.RegisterType<ChatService>().As<IChatService>().SingleInstance(); // classic "service", has dependency on DbContext
builder.RegisterType<ChatHub>().ExternallyOwned(); // SignalR hub
builder.RegisterType<UpdateStatusesJob>().InstancePerDependency(); // Hangfire job
builder.RegisterType<HomeController>().InstancePerRequest(); // ASP.NET MVC controller
IContainer container = builder.Build();
Run Code Online (Sandbox Code Playgroud)
对于 MVC,我使用 Autofac.MVC5 nuget 包。依赖解析器:
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
Run Code Online (Sandbox Code Playgroud)
对于 SignalR,我使用 Autofac.SignalR nuget 包。依赖解析器:
GlobalHost.DependencyResolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
Run Code Online (Sandbox Code Playgroud)
我的signalR集线器以这种方式实例化(http://autofac.readthedocs.org/en/latest/integration/signalr.html#managing-dependency-lifetimes):
private ILifetimeScope _hubScope;
protected IChatService ChatService;
public ChatHub(ILifetimeScope scope) {
_hubScope = scope.BeginLifetimeScope(); // scope
ChatService = _hubScope.Resolve<IChatService>(); // this service is used …Run Code Online (Sandbox Code Playgroud) 所以我目前正在使用一个使用Entity Framework的ASP.NET MVC Web应用程序,我也使用Ninject进行依赖注入.
所以基本上,目前,这是我用Ninject注册我的DbContext和服务的方式.
kernel.Bind<DbContext>().To<MyApplicationContext>().InSingletonScope();
kernel.Bind<IAccountService>().To<AccountService>().InSingletonScope();
kernel.Bind<IRegionService>().To<RegionService>().InSingletonScope();
kernel.Bind<IRoleService>().To<RoleService>().InSingletonScope();
Run Code Online (Sandbox Code Playgroud)
我注册它们InSingletonScope,这意味着它们只会被创建一次并在应用程序的整个生命周期中使用(至少我是如何理解的).
控制器:
private IAccountService _accountService;
public MemberController(IAccountService accountService)
{
_accountService = accountService;
}
Run Code Online (Sandbox Code Playgroud)
但是,我深深感到这个单例范围会导致我的Web应用程序出现问题,特别是对于Entity Framework的上下文,因为它是单例.
我已经面临一个小问题,如果我使用SQL Management Studio手动更新数据库,我的Web应用程序的实体框架中的数据将不会更新,直到我重新启动应用程序(似乎是EF中的一些缓存机制).
-
但是,如果我删除了InSingletonScope,我将随机从EF获取错误说:
IEntityChangeTracker的多个实例不能引用实体对象
我理解为什么会发生这种情况,因为初始化的DbContext AccountService可能与说不同RegionService.但我不知道如何解决这个问题.
我对依赖注入的理解仍然非常有限,所以有人可以建议吗?
-
编辑:我已经尝试改为InRequestScope所有注射,但我仍然得到
IEntityChangeTracker的多个实例不能引用实体对象
尝试从我的应用程序中的另一个服务插入具有相关对象(外键)的新实体时.这意味着他们仍在使用不同的DbContext,发生了什么?!
最后编辑:好的我发现了问题,这是我的缓存机制缓存了以前的请求,导致所有后续请求的关系问题.
c# asp.net-mvc entity-framework dependency-injection ninject
我们将 ASP.NET Identity 2.2 与 ASP.NET MVC 5.2、Entity Framework 6.2 和 Unity 5.7 一起使用。
我们有一个ConnectUserManager派生自 ASP.NET Identity 的UserManager. 每次都会UserStore传递一个新构造的UserManager。
的ConnectUserManager(以及UserManager)的生命周期是每个请求:
Container.RegisterType<ConnectUserManager>(
new PerRequestLifetimeManager(),
new InjectionConstructor(
Container.Resolve<ConnectDbContext>(),
Container.Resolve<ITemplateManager>(),
Settings.MaxFailedAccessAttemptsBeforeLockout,
Settings.AccountLockoutTimeSpan));
Run Code Online (Sandbox Code Playgroud)
当我们需要显示给定用户的详细信息时,控制器操作会检索用户,如下所示:
public async Task<ActionResult> Details(int id)
{
var user = await UserManager.FindByIdAsync(id);
...
}
Run Code Online (Sandbox Code Playgroud)
UserManager注入的属性在哪里:
[Dependency]
public ConnectUserManager UserManager { get; set; }
Run Code Online (Sandbox Code Playgroud)
问题user似乎来自缓存:数据库中的修改似乎对我们的应用程序显示的内容没有任何影响。
这段代码已经投入生产一年了,我们从来没有遇到过任何问题:当我们的代码修改用户时,缓存似乎正确地失效了。
我们现在才注意到这个问题,因为当 Identity 锁定用户时,它会更新用户的LockoutEndDateUtc属性,但似乎没有使缓存失效,并且我们LockoutEndDateUtc在显示中得到了一个陈旧的值。
我们做错了什么? …
c# asp.net-mvc entity-framework unity-container asp.net-identity
c# ×4
asp.net-mvc ×3
autofac ×3
ninject ×3
.net ×1
asp.net ×1
datacontext ×1
dispose ×1
hangfire ×1
lifecycle ×1
partial ×1
ravendb ×1
resolve ×1
signalr ×1
unit-of-work ×1