我有以下配置:
builder.Register<EntityContext>().As(
c=> {
var entityCtx = new EntityContext();
//snip snip: some config stuff
return entityCtx;
}).As<MyDbContext>().InstancePerLifetimeScope();
Run Code Online (Sandbox Code Playgroud)
EntityContext
显然继承自MyDbContext
又继承自DbContext
.
在我的存储库的构造函数中,我通常将它们用作
...
public MyRepository(MyDbContext context) {...}
Run Code Online (Sandbox Code Playgroud)
这确保每个 http 请求都有一个 ctx,这正是我想要的。但是现在我需要一个特定的存储库,我想要一个不同于通常使用的 EntityContext实例。
你会如何做到这一点?我想到了以下几点:
Register<EntityContext>()....As<DbContext>()...
还有其他想法吗?
我这样做:https : //stackoverflow.com/questions/12069002/autofac-resolve-with-and-without-named-parameter
我注册了一个接口。对于初始化,需要一个参数。第一次调用将传递此参数。
在另一个地方,我也想解析这个接口实例,但我不能传递这个参数。是否可以检查此接口是否已解析(在当前范围内。我使用 ASP.NET WEB API)?如果我在没有参数的情况下解决它,我会得到一个例外。
我需要检查当前 HttpRequest-scope 中是否已经解析(所以我可以在不传递参数的情况下获取它,因为如果它已经解析,注册的创建委托将不会被调用两次)
m_builder.Register<IMyClass((c, p) =>
{
//...
return new MyClass;
}).InstancePerHttpRequest();//.InstancePerApiRequest();
Run Code Online (Sandbox Code Playgroud) 如何配置Autofac容器,以便它根据operation-parameter(请求对象)的属性值解析WCF服务的依赖关系?
例如,鉴于此数据合同......
[DataContract]
public class MyRequest
{
[DataMember]
public bool MyBool { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这个WCF服务......
public class MyWcfService : IWcfService
{
private IService m_service;
public MyWcfService(IService service)
{
m_service = service;
}
public virtual MyResponse Operation(MyRequest request) { }
}
Run Code Online (Sandbox Code Playgroud)
和这些依赖...
public interface IService { }
public class TypeA : IService { }
public class TypeB : IService { }
Run Code Online (Sandbox Code Playgroud)
如果MyBool等于true,我希望容器解析TypeA,否则解决TypeB.这个功能可用吗?我应该以不同方式解决问题吗?
约束:
我们在具有 DDD 架构的 asp.net MVC 中应用了 autofac IOC 容器。我们正在尝试使用不同的数据库连接注册两个 dbcontext。但只有最后一个生效。我们正在使用实体框架 4.4.0。这是代码。
var masterDataSettingManager = new SaasDataSettingManager();
if (masterDataSettingManager.LoadSettings() != null)
{
var masterProviderSettings = masterDataSettingManager.LoadSettings();
builder.Register(c => masterDataSettingManager.LoadSettings()).As<DataSettings>();
builder.Register(x => new EfDataProviderManager(x.Resolve<DataSettings>())).As<BaseDataProviderManager>().InstancePerDependency();
builder.Register(x => (IEfDataProvider)x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IDataProvider>().InstancePerDependency();
builder.Register(x => (IEfDataProvider)x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IEfDataProvider>().InstancePerDependency();
if (masterDataSettingManager != null && masterProviderSettings.IsValid())
{
var efDataProviderManager = new EfDataProviderManager(masterDataSettingManager.LoadSettings());
var dataProvider = (IEfDataProvider)efDataProviderManager.LoadDataProvider();
dataProvider.InitConnectionFactory();
var dbProviderFactory = efDataProviderManager.LoadDbProviderFactories();
builder.Register<IDbContext>(c => new MyDbContext1(masterProviderSettings.DataConnectionString, dbProviderFactory)).InstancePerHttpRequest();
}
else
{
builder.Register<IDbContext>(c => new MyDbContext1(masterDataSettingManager.LoadSettings().DataConnectionString)).InstancePerHttpRequest();
}
}
//data layer
var dataSettingsManager = new DataSettingsManager(); …
Run Code Online (Sandbox Code Playgroud) 有没有办法确定哪个调用者/依赖项正在解析它所依赖的实例?这就是我的想法
public class A
{
public A()
{
Console.Write("I am being resolved by {0}");
}
}
public class B
{
public B(A a)
{
//Should print: A being resolved by B
}
}
public class C
{
public C(A a)
{
//Should print: A being resolved by C
}
}
Run Code Online (Sandbox Code Playgroud)
我猜测在多个依赖项之间共享的单个实例可能有点棘手,但我特意查找每个依赖项解析的实例,因此在上面的示例中将有两个B实例.
FWIW,我的IoC容器是Autofac,它在MVC Web应用程序的上下文中运行
我在 Web 应用程序中有一个广泛使用的缓存接口,其实现当前注册为SingleInstance
.
当前的缓存实现假定单线程初始化,但一旦初始化是不可变的,因此可以在多个线程之间安全地共享。
但是,这意味着当前,如果基础值发生更改,则缓存不会更新,直到应用程序重新启动。虽然更新底层值很少见,但我们现在希望提供修改底层值的应用程序行为,然后告诉缓存刷新。
我可以修改缓存实现以使用锁定,或者可能利用 .NET 并发集合之一来安全地更新缓存值。
但是,我想知道 autofac 是否提供了一种功能,允许我在下一个请求中为新实例更改已注册的实例,以便不需要修改缓存实现本身。
所以理想的行为是,当我们修改底层值时,我们会触发一个新缓存实例的创建。一旦实例完成初始化,所有正在进行的请求将继续使用旧的缓存实例,任何新的 http 请求范围解析为更新的实例。
autofac 是否提供内置方式来支持这种情况?
我正在尝试在我的组织中采用BDD,因为C#.Net是我们的主要开发模式,Specflow是我们对"任何黄瓜"的最佳选择.
但是,我过去曾是一名Spring爱好者,但在我的公司,我们正在将Autofac用于应用程序的各个部分.但是,我找不到任何解释"如何"的资源,可以使用Autofac"触发"Specflow的BDD测试并提供必要的依赖连接.
我计划让Autofac负责实例化,连接和执行所有内容而不是执行Specflow,并且让调用Autofac的方法遍布各处,即使用Autofac作为服务定位器而不是DI/IoC容器.甚至可以这样做,还是我以错误的方式看待它并且有更好的方法来实现同样的目标?或者我应该完全依赖Specflow的"内部容器"进行DI并完全忘记Autofac?
可能的方法:
优点缺点:
我不确定如何实现它们中的任何一个,如果最好让Specflow处理DI并忘记Autofac或让Autofac解雇所有内容或者是否存在中间地带?
当前的BDD设置:Specflow,Selenium/PhantomJS,Xunit.希望与Autofac结合使用.
我想加入使用策略模式和 DI。
class A : IBase
{
public void Do();
}
class B : IBase
{
public void Do();
}
interface IBase
{
void Do();
}
class Context()
{
private _usedClass;
void SetClass(IBase usedClass)
{
_usedClass = usedClass;
}
public void Do()
{
_usedClass.Do();
}
}
void Main()
{
var context = new Context();
var someEnum = SomeMethod();
//how to use here DI resolve to get appropriate class instead of if/else?
if (someEnum == MyEnum.A)
context.SetClass(new A());
else if (someEnum …
Run Code Online (Sandbox Code Playgroud) .net design-patterns dependency-injection strategy-pattern autofac
所以我在MVC中使用autofac,所以我的控制器可以在那里注入构造函数,我有我的Global.asax我有以下代码片段,它的工作原理.
// Register your MVC controllers.
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<PurchaseOrderSearchService>().As<IPurchaseOrderSearchService>().WithParameter("context", new PurchaseOrderManagerContext());
// Set the dependency resolver to be Autofac.
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
Run Code Online (Sandbox Code Playgroud)
问题是我不想一遍又一遍地使用builder.RegisterType,对于我的所有服务.那我该怎么做?
我想我想要的是那种东西
builder.RegisterAssemblyTypes(foo)
.Where(t => t.Name.EndsWith("Services"))
.WithParameter("context", new PurchaseOrderManagerContext());
Run Code Online (Sandbox Code Playgroud)
但不知道foo应该是什么.或者如果RegisterAssemblyTypes是正确的方式.我知道按惯例编码是解决方案,但不确定约定是什么.我的所有服务都将以字服务结束并具有界面
所以FooService将具有接口IFooService,而BarService将具有接口IBarService
还应该指出所有服务都存在于名为PurchaseOrderManager.Service的类库中
我想将Autofac添加到.Net Core应用程序中.我已经尝试从Autofac执行所有步骤:入门教程,我已安装Autofac.Extensions.DependencyInjection
,已更新Program
类,但无法像示例中那样添加autofac.
得到错误
错误CS1061'IServiceCollection'不包含'AddAutofac'的定义,并且没有扩展方法'AddAutofac'可以找到接受类型'IServiceCollection'的第一个参数(你是否缺少using指令或程序集引用?)
重新安装nuget包,清理和重建解决方案,关闭VS - 没有帮助的东西.
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.ConfigureServices(services => services.AddAutofac()) //here is problem
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
Run Code Online (Sandbox Code Playgroud)
Autofac的版本 - 4.6.2版本的Autofac.Extensions.DependencyInjection - 4.2.0