例:
public abstract class BaseControler : Controller
{
public IUnitOfWork UnitOfWork { get; set; }
}
public class HomeController : BaseControler
{
readonly IUserRepository _userRepository;
// :-)
public HomeController(IUserRepository userRepository)
{
_userRepository = userRepository;
}
}
Run Code Online (Sandbox Code Playgroud)
我们都知道在需要依赖时我们必须使用Constructor Injection.如果它是可选的依赖项,我们可以使用Property Injection.
但是当你的基类只需要依赖时你应该怎么做?
当您使用构造函数注入时,我认为会污染所有派生类.
public abstract class BaseControler : Controller
{
readonly IUnitOfWork _unitOfWork;
public BaseControler(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
}
public class HomeController : BaseControler
{
readonly IUserRepository _userRepository;
// …Run Code Online (Sandbox Code Playgroud) c# dependency-injection inversion-of-control property-injection
实例化类时,Windsor默认将该类的所有公共属性视为可选依赖项,并尝试满足它们.在我的情况下,这会创建一个相当复杂的循环依赖项,导致我的应用程序挂起.
我怎样才能明确告诉温莎城堡它不应该试图满足公共财产?我假设必须有一个属性到那个程度.我无法找到它,请告诉我相应的命名空间/程序集.
如果有任何方法可以在没有属性的情况下执行此操作(例如Xml配置或通过代码配置),这将是更可取的,因为发生这种情况的特定库迄今为止不需要依赖于城堡.
我有以下课程:
public interface IServiceA
{
string MethodA1();
}
public interface IServiceB
{
string MethodB1();
}
public class ServiceA : IServiceA
{
public IServiceB serviceB;
public string MethodA1()
{
return "MethodA1() " +serviceB.MethodB1();
}
}
public class ServiceB : IServiceB
{
public string MethodB1()
{
return "MethodB1() ";
}
}
Run Code Online (Sandbox Code Playgroud)
我使用Unity for IoC,我的注册看起来像这样:
container.RegisterType<IServiceA, ServiceA>();
container.RegisterType<IServiceB, ServiceB>();
Run Code Online (Sandbox Code Playgroud)
当我解析一个ServiceA实例时,serviceB将是null.我该如何解决这个问题?
c# ioc-container inversion-of-control unity-container property-injection
我的课程中有一个属性用于记录服务.
private ILogger logger = NullLogger.Instance;
public ILogger Logger
{
get { return logger; }
set { logger = value; }
}
Run Code Online (Sandbox Code Playgroud)
我在组件注册中有这个:
container.AddFacility<LoggingFacility>(x => new LoggingFacility(LoggerImplementation.Log4net));
Run Code Online (Sandbox Code Playgroud)
然而,温莎似乎没有注入记录器 - 我错过了什么?
我正在寻找有关为IoC设计对象的最佳方法的建议
假设我有一个对象(Service)依赖于向Ioc注册的DataContext.
但它还需要一个名称属性,我可以像这样设计对象:
class Service
{
public Service(IDataContext dataContext,
string name)
{
this._dataContext = dataContext;
this._name = name
}
public string Name
{
get
{
return _name;
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是使用Ioc容器变得非常复杂,因为字符串对象如名称不容易注册,并且Ioc容器的使用变得复杂:因此解决方案变得混乱:
var service = Ioc.Resolve<Service>( ?? )
Run Code Online (Sandbox Code Playgroud)
另一种方法是将其设计如下:
class Service
{
public Service(IDataContext dataContext)
{
this._dataContext = dataContext;
}
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
分辨率现在更容易:
var service = Ioc.Resolve<Service>();
service.Name = "Some name";
Run Code Online (Sandbox Code Playgroud)
唯一的缺点是不再需要指定名称.我想听听DI或IoC专家如何设计这个并且仍然对混凝土Ioc容器技术保持相当不可知.
我知道很多取决于你想如何使用它,如果name真的是可选的,选项2将是完美的.但是在需要名称的情况下,你可以在代码的另一个点添加验证步骤,而是去设计使Ioc更简单.
思考?
c# dependency-injection inversion-of-control property-injection constructor-injection
我有期望几个属性由Ninject 2被注入的方法属性,但userSession并jobRepository都上来为空:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class JobAttribute : ActionFilterAttribute {
[Inject]
private IUserSession userSession;
[Inject]
private IJobRepository jobRepository;
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var filter = new JobFilter(userSession, jobRepository);
filter.OnActionExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)
这是控制器中的方法:
[AcceptGet, Job]
public ActionResult Dimensions(Job job) {
return View(job.Building);
}
Run Code Online (Sandbox Code Playgroud)
我知道我的设置有效,因为如果我在控制器上使用构造函数注入,则会注入控制器的参数.虽然需要使用属性注入,但这对属性没有多大帮助.我在这里错过了什么吗?
以下是Global.asax.cs的相关部分:
public class MvcApplication : Ninject.Web.Mvc.NinjectHttpApplication {
protected override void OnApplicationStarted() {
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
...snip...
protected override IKernel CreateKernel() {
return new StandardKernel(
new RepositoryConfiguration(),
new AuthenticationModule(),
new …Run Code Online (Sandbox Code Playgroud) c# asp.net-mvc ninject property-injection actionfilterattribute
我想@Value在一个属性上使用,但我总是得到0(在int上).
但是在构造函数参数上它可以工作.
例:
@Component
public class FtpServer {
@Value("${ftp.port}")
private int port;
public FtpServer(@Value("${ftp.port}") int port)
{
System.out.println(port); // 21, loaded from the application.properties.
System.out.println(this.port); // 0???
}
}
Run Code Online (Sandbox Code Playgroud)
该对象是spring管理的,否则构造函数参数将不起作用.
有谁知道导致这种奇怪行为的原因是什么?
java spring dependency-injection property-injection spring-boot
关于循环引用的autofac wiki页面说使用:
cb.Register<DependsByProp>().OnActivated(ActivatedHandler.InjectUnsetProperties);
Run Code Online (Sandbox Code Playgroud)
但看起来ActivatedHandler在2.4.5中不再存在了.在源代码中挖掘,我找到了该类的实现,因此我在OnActivated中添加了方法实现.不幸的是,它仍然无效.
我在这里整理了一个最小的repro,看起来就像Wiki页面上的内容.
class M
{
public VM VM { get; set; }
public M()
{
}
}
class VM
{
public VM(M m)
{
}
}
[Fact]
void CanResolveCircular()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<VM>();
builder.RegisterType<M>().OnActivated(e => e.Context.InjectUnsetProperties(e.Instance));
using (var container = builder.Build())
{
var m = container.Resolve<M>();
Assert.NotNull(m);
}
}
Run Code Online (Sandbox Code Playgroud)
当尝试Resolve时,此代码仍会引发堆栈溢出异常.我错过了什么?让Autofac处理循环依赖的正确方法是什么?
dependency-injection circular-dependency autofac property-injection
使用Autofac,我可以使用以下代码注册一个类来解析使用属性注入的接口:
builder.RegisterType<Log4NetAdapter>()
.As<ILogger>()
.PropertiesAutowired()
.InstancePerDependency();
Run Code Online (Sandbox Code Playgroud)
但是,我的Log4NetAdapter类有一个构造函数参数,需要调用类的名称.这样,我可以根据调用类的名称记录事件.
public class Log4NetAdapter : ILogger
{
private readonly ILog _logger;
public Log4NetAdapter(string logName)
{
_logger = LogManager.GetLogger(logName);
}
...
}
Run Code Online (Sandbox Code Playgroud)
typeof(dependency).Name如果每个依赖项都有自己的Log4NetAdapter实例,我怎样才能将依赖项的名称(即)注入到属性注入类的构造函数中?
我有两个类,一个通过注册类型来设置容器,另一个包含我想要注入的静态属性.我的问题是属性永远不会通过注入设置,因此当我调用它的方法时,该属性始终为null.
public class ClassOne
{
public void Method()
{
Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
}
}
public static class ClassTwo
{
[Dependency]
public static IClass SomeProperty { get; set; }
public static void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我删除Dependency属性并在ClassOne中做一个简单的
ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");
Run Code Online (Sandbox Code Playgroud)
它工作正常,但我想知道是否可以这样做而不明确地为属性赋值(即容器可以通过属性注入)?
编辑:
谢谢.我已经从ClassTwo中删除了静态声明,并在ClassOne中添加了RegisterType和Resolve for ClassTwo,还添加了InjectionProperty:
Container.RegisterType<IClass, ClassImplOne>("ImplOne", new InjectionProperty("SomeProperty"));
Run Code Online (Sandbox Code Playgroud)
但它仍然不起作用:S
c# containers dependency-properties unity-container property-injection
我可以在MVC Core中轻松使用Constructor Parameter Injection.但是不支持Property Injection.我尝试使用AutoFac但也失败了.
那么如何在MVC Core中使用Property Injection.
这是AutoFac的代码
services.AddMvc();
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Test2>().As<ITest>();
builder.RegisterType<HomeController>().PropertiesAutowired();
builder.Populate(services);
var container = builder.Build();
//The following code works
HomeController test2 = container.Resolve<HomeController>();
return new AutofacServiceProvider(container);
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试编写一个使用 Spring Data Mongo 存储库的集成测试类。我使用de.flapdoodle.embed.mongo依赖项提供的嵌入式 Mongo 实例。Spring Data 文档指定我们只需将此依赖项放在项目EmbedMongoAutoConfiguration中,其余部分由它来处理。
现在,没关系,将端口设置为0使自动配置过程找到一个空闲端口来启动 mongo 实例。
此功能对我来说是必要的,以避免与其他测试(这些测试与我公司的其他项目一起在 Jenkins CI 服务器上运行)发生冲突。
现在问题来了,我希望能够在我的每个测试方法运行之前从某个外部文件注入一些测试数据。我发现 NoSQL Unit 可以通过一个简单的方法注释和一个 JUnit 来做到这一点@Rule。
下面是一个例子:
@Value("${local.mongo.port}")
private int mongoPort; // <- still 0 a the time the Rule below is created.
@Rule
public MongoDbRule managedMongoDb = new MongoDbRule(MongoDbConfigurationBuilder.mongoDb().databaseName("myAwesomeDb").port(mongoPort).build());
@Test
@UsingDataSet(locations = "testdata.json", loadStrategy = LoadStrategyEnum.CLEAN_INSERT)
public void testMyData() {
// ...
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,@Rule需要在其构建器中使用 Mongo 端口来实例化底层的 MongoClient,但是在实例化 @Rule 时,Spring 上下文尚未完全初始化并且EmbeddedMongoAutoConfiguration …
我正在使用OWIN中间件(使用startup.cs而不是global.asax)在我的ASP.NET MVC 5 Web应用程序中连接Autofac依赖注入,并尝试使用属性注入在Controller中设置公共变量.
我正在玩属性注入,让Autofac自动在LoginController中设置Test属性.
public interface ITest
{
string TestMethod();
}
public class Test : ITest
{
public string TestMethod()
{
return "Hello world!";
}
}
public class LoginController : Controller
{
public ITest Test { get; set; }
public LoginController()
{
var aaa = Test.TestMethod();
// Do other stuff...
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的startup.cs的样子.我一直在玩,所以可能不需要这些代码(或导致我的问题?).
public class Startup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
builder.RegisterType<Test>().As<ITest>().SingleInstance();
builder.Register(c => new Test()).As<ITest>().InstancePerDependency();
builder.RegisterType<ITest>().PropertiesAutowired();
builder.RegisterType<LoginController>().PropertiesAutowired();
builder.RegisterModelBinderProvider();
builder.RegisterFilterProvider();
var container …Run Code Online (Sandbox Code Playgroud) c# ×8
autofac ×4
java ×2
.net ×1
.net-core ×1
asp.net-mvc ×1
containers ×1
junit-rule ×1
mongodb ×1
ninject ×1
spring ×1
spring-boot ×1
spring-data ×1