是否可以使用 Nancyfx 默认 TinyIoc 容器的 属性 注入?
Is it possible to use Property Injection with Nancyfx default TinyIoc container?
是的,我知道,最好使用构造函数注入,而且我大部分时间都在使用它,但是,在这种情况下我喜欢使用 属性 注入:
我有一个存储库基础 class,它具有数据库工厂的依赖项以及读取应用程序设置的服务(ConfigurationManager 的抽象)
public abstract class RepositoryBase(){
public IDatabaseFactory DatabaseFactory { get; set; }
public IAppConfigService AppConfig { get; set; }
protected Database Db
{
get
{
var db = DatabaseFactory.Get();
... not relevant code ...
return db;
}
}
}
我不想在这里使用构造函数依赖项,因为这会迫使我将构造函数添加到我的所有存储库中,我可以这样做,但我不想这样做。更糟糕的问题是,如果出于某种原因我向 RespositoryBase class 添加了一个日志服务,我将不得不将这个新的依赖项添加到我所有存储库 classes 的构造函数中,这并不酷。
我可以使用诸如服务聚合之类的模式来避免修改 RepositoryBase class,但这看起来太复杂了,我真的很想保持简单,以便每个人都能理解发生了什么(包括我) .
那么,是否可以通过 Nancy / TinyIOC 注入这些依赖项?
是的,TinyIoC supports property injection。这在南希也应该有效。
如果我们查看 TinyIoC 的代码,我们会发现对象创建后没有属性注入代码:https://github.com/NancyFx/Nancy/blob/master/src/Nancy/TinyIoc/TinyIoC.cs#L3693 and in the original repo too: https://github.com/grumpydev/TinyIoC/blob/master/src/TinyIoC/TinyIoC.cs#L3849
如果我们用类似的东西修补代码:
try
{
object o = null;
#if USE_OBJECT_CONSTRUCTOR
var constructionDelegate = CreateObjectConstructionDelegateWithCache(constructor);
o = constructionDelegate.Invoke(args);
#else
o = constructor.Invoke(args);
#endif
BuildUp(o, ResolveOptions.Default);
return o;
}
catch (Exception ex)
{
throw new TinyIoCResolutionException(typeToConstruct, ex);
}
它会起作用,但我们会遇到另一个问题。主要问题是 BuildUp 将尝试填充它找到的所有空引用。并且没有合适的 ResolveOptions 来避免这种情况:(我说得对吗?
...
我终于创建了 Inject 属性。您可以使用 [Inject] 标记任何引用类型 属性,您将获得所需的行为。
来源可在此处获得:https://github.com/AIexandr/Nancy/blob/master/src/Nancy/TinyIoc/TinyIoC.cs
所有更改都向后兼容。
是的,我知道,最好使用构造函数注入,而且我大部分时间都在使用它,但是,在这种情况下我喜欢使用 属性 注入:
我有一个存储库基础 class,它具有数据库工厂的依赖项以及读取应用程序设置的服务(ConfigurationManager 的抽象)
public abstract class RepositoryBase(){
public IDatabaseFactory DatabaseFactory { get; set; }
public IAppConfigService AppConfig { get; set; }
protected Database Db
{
get
{
var db = DatabaseFactory.Get();
... not relevant code ...
return db;
}
}
}
我不想在这里使用构造函数依赖项,因为这会迫使我将构造函数添加到我的所有存储库中,我可以这样做,但我不想这样做。更糟糕的问题是,如果出于某种原因我向 RespositoryBase class 添加了一个日志服务,我将不得不将这个新的依赖项添加到我所有存储库 classes 的构造函数中,这并不酷。
我可以使用诸如服务聚合之类的模式来避免修改 RepositoryBase class,但这看起来太复杂了,我真的很想保持简单,以便每个人都能理解发生了什么(包括我) .
那么,是否可以通过 Nancy / TinyIOC 注入这些依赖项?
是的,TinyIoC supports property injection。这在南希也应该有效。
如果我们查看 TinyIoC 的代码,我们会发现对象创建后没有属性注入代码:https://github.com/NancyFx/Nancy/blob/master/src/Nancy/TinyIoc/TinyIoC.cs#L3693 and in the original repo too: https://github.com/grumpydev/TinyIoC/blob/master/src/TinyIoC/TinyIoC.cs#L3849
如果我们用类似的东西修补代码:
try
{
object o = null;
#if USE_OBJECT_CONSTRUCTOR
var constructionDelegate = CreateObjectConstructionDelegateWithCache(constructor);
o = constructionDelegate.Invoke(args);
#else
o = constructor.Invoke(args);
#endif
BuildUp(o, ResolveOptions.Default);
return o;
}
catch (Exception ex)
{
throw new TinyIoCResolutionException(typeToConstruct, ex);
}
它会起作用,但我们会遇到另一个问题。主要问题是 BuildUp 将尝试填充它找到的所有空引用。并且没有合适的 ResolveOptions 来避免这种情况:(我说得对吗?
...
我终于创建了 Inject 属性。您可以使用 [Inject] 标记任何引用类型 属性,您将获得所需的行为。
来源可在此处获得:https://github.com/AIexandr/Nancy/blob/master/src/Nancy/TinyIoc/TinyIoC.cs 所有更改都向后兼容。