读完这篇关于命令处理程序装饰的文章后,今天谈到了一个有趣的话题。我想看看是否可以使用 Unity 而不是SimpleInjector来实现该模式,到目前为止,事实证明这非常困难。
我要做的第一件事就是安装UnityAutoRegistration来解析开放通用ICommandHandler<TCommand>接口。目前该方面的解决方案如下:
Container = new UnityContainer().LoadConfiguration();
Container.ConfigureAutoRegistration()
.ExcludeSystemAssemblies()
.Include(type => type.ImplementsOpenGeneric(typeof(ICommandHandler<>)),
(t, c) => c.RegisterType(typeof(ICommandHandler<>), t)
)
.ApplyAutoRegistration()
;
Run Code Online (Sandbox Code Playgroud)
这适用于第一部分,解决任何单个 ICommandHandler<TCommand>. 到目前为止,令人沮丧的是实现装饰处理程序。一旦我添加第二个ICommandHandler<TCommand>装饰器,Unity 就会抛出 StackOverflowException。我对 Unity 内部了解不够,但我猜这是因为它无法确定要解析到哪个实例(命令处理程序或命令处理程序装饰器),因为两者都实现了该ICommandHandler<TCommand>接口。
谷歌搜索让我首先找到了这篇文章,它解释了如何用我认为的蛮力方法来做到这一点。我还找到了这些 相关 页面,但没有一个是解决我的问题的完整解决方案(而且我太无知了,无法自己弄清楚)。
然后我找到了这篇文章,它似乎解决了我同样的担忧。然而,beefy 的解决方案并没有考虑处理开放仿制药。目前,我们的大多数依赖项都是从 .config 文件中的统一部分加载的,因此我不想为每个处理程序或装饰器编写大量编译代码。似乎拥有某种 UnityContainerExtension 和 DecoratorBuildStrategy 是正确的方法,但我无法弄清楚。我已经玩了一段时间的 Beefy 代码,但完全陷入困境。我尝试修改他的代码以考虑泛型导致了 BadImageFormatExceptions(尝试加载格式不正确的程序。(来自 HRESULT 的异常:0x8007000B))。
我喜欢这样做来实现装饰器链接的想法,因为它很短,并且每个关注点只有 1 行:
var container = new Container();
// Go look in all assemblies and register all …Run Code Online (Sandbox Code Playgroud) .net c# dependency-injection unity-container simple-injector
UnityContainer.CreateChildContainer()Unity IoC 5.8.x 版本中曾经有一个方法。但是它从 5.9.x 版本开始就消失了。这是否意味着整个子容器功能已被删除?有没有其他方法可以实现这一目标?
因此,我使用 Unity MVC-4 来实现依赖注入,它非常适合我的Controller类,但是一旦我尝试注入我的非控制器类,我就会得到NullReferenceException,并且我可以看到我注入的对象没有由框架初始化。我会给你我正在使用的相应类:
Controller类(DI作品):
public class HomeController : Controller
{
IMyService _myService;
#region CTOR
public HomeController(IMyService myService)
{
_myService = myService;
}
#endregion
public string GetMyString()
{
string mystring=string.Empty;
try
{
mystring = _myService.GetMyStringFromDLL();
}
catch (Exception ex)
{
StringBuilder str = new StringBuilder();
str.AppendLine("Exception in method GetMyString, Error msg: " + ex.Message);
WriteLog(sb);
}
return mystring;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在非控制器方法中做同样的事情(DI 在这里不起作用),我会得到NullReferenceException:
public inteface IMyLogic
{
string GetMyString();
}
public class MyLogic: IMyLogic …Run Code Online (Sandbox Code Playgroud) 这是一个C#Asp.net MVC项目.
我目前在global.asax.cs中设置了Unity映射.我想将容器设置从代码移动到web.config.
我自己的类型一切都很好,但现在我需要翻译这一行:
container.RegisterInstance(System.Web.Security.Membership.Provider);
(所有其他配置行都是container.Register 类型).
我根本没有走得太远.如果我甚至包括
<typeAliases>
<!-- others elided -->
<typeAlias
alias="MembershipProvider"
type="System.Web.Security.MembershipProvider, System.Web"></typeAlias>
Run Code Online (Sandbox Code Playgroud)
它死了配置错误:
The value of the property 'type' cannot be parsed. The error is: Could not load file or assembly 'System.Web' or one of its dependencies. The system cannot find the file specified.
Run Code Online (Sandbox Code Playgroud)
所以这很奇怪 - 似乎它没有在GAC中寻找它来解决它?或者System.Web不在appdomain中?
如果我手动将System.Web复制到bin文件夹,我可以继续,并解决问题的关键:你如何RegisterInstance System.Web.Security.MembershipProvider - > System.Web.Security.Membership.Provider?
<type type="MembershipProvider" mapTo="System.Web.Security.Membership.Provider, System.Web"></type>
Run Code Online (Sandbox Code Playgroud)
给出:
无法从程序集"System.Web"加载"System.Web.Security.Membership.Provider"类型.
正如所料,因为它不是一种类型.
谢谢你的任何指示.
当我
container.RegisterType<IInterface, MyClass>();
Run Code Online (Sandbox Code Playgroud)
一切正常,所有依赖属性都注释为:
[Dependency]
Run Code Online (Sandbox Code Playgroud)
通过容器解决.
但是,我现在有一个int属性,我也想通过容器来解决.它不是在构造函数中传递的,而是作为公共属性传递的.所以我尝试了这个:
container.RegisterType<IInterface, MyClass>(
new InjectionProperty("PropertyName", 1)
);
Run Code Online (Sandbox Code Playgroud)
现在该属性被注入,但使用[Dependency]注释的所有其他属性都为null并且未解析.如果我将InjectionProperty用于一个属性,我现在是否必须显式声明具有[Dependency]属性的所有其他属性?或者有更好的方法吗?
谢谢.
任何人都可以给我一个很好的例子,将犀牛嘲讽,nunit和团结一起使用.我正在阅读每个方面的帮助,但似乎没有任何关于如何一起使用它们的好示例项目以及使用它们设置项目/测试项目的方法.即你在测试项目中创建新的ioc容器,指向虚拟类.然后犀牛在哪里进入它.
谢谢你的帮助.
我有一个单独的接口,这是由2个类使用.我正在使用统一配置来基于接口识别实例.
现在我想知道如何注册这些类型,以便我可以基于单个接口本身调用适当的实现.
我是一个独立的开发人员,Pluralsight是我帮助我理解Repository和IoC之类的东西,我正在学习.但是我发现这种模式很难使用.
所以我使用Unity IoC,然后ModelContainer上课;
public static class ModelContainer
{
private static IUnityContainer instance;
static ModelContainer()
{
instance = new UnityContainer();
}
public static IUnityContainer Instance
{
get
{
instance.RegisterType<ISCD_CallDiaryRepository, SCD_CallDiaryRepository>(new HierarchicalLifetimeManager());
instance.RegisterType<ICompanyRepository, CompanyRepository>(new HierarchicalLifetimeManager());
instance.RegisterType<ISubcontractorRepository, SubcontractorRepository>(new HierarchicalLifetimeManager());
instance.RegisterType<ITradeRepository, TradeRepository>(new HierarchicalLifetimeManager());
instance.RegisterType<IEmployeeRepository, EmployeeRepository>(new HierarchicalLifetimeManager());
instance.RegisterType<ISubcontractorTradeRepository, SubcontractorTradeRepository>(new HierarchicalLifetimeManager());
instance.RegisterType<ICountyRepository, CountyRepository>(new HierarchicalLifetimeManager());
instance.RegisterType<IAddressLineRepository, AddressLineRepository>(new HierarchicalLifetimeManager());
return instance;
}
}
}
Run Code Online (Sandbox Code Playgroud)
允许我在我的控制器的构造函数中实例化存储库类;
public SubcontractorController(
ISubcontractorRepository subcontractorRepository,
ISubcontractorTradeRepository subcontractorTradeRepository,
ICompanyRepository companyRepository,
ISCD_CallDiaryRepository scdCallDiaryRepository,
ITradeRepository tradeRepository,
IAddressLineRepository addressLineRepository)
{
this.SubcontractorRepository = subcontractorRepository;
this.SubcontractorTradeRepository = subcontractorTradeRepository; …Run Code Online (Sandbox Code Playgroud) 是否可以在UnityContainer中配置的另一种类型的构造函数中实例化UnityContainer中配置的类型?根据我目前的解决方案,我得到了一个
ResolutionFailedException:
依赖项的解析失败,type ="Sample.IMyProcessor",name ="(none)".
在解决时发生异常:
例外是:VerificationException - 操作可能会破坏运行时的稳定性.
问题是我的第二个类(FileLoader)有一个应该在第一个构造函数中计算的参数:
MyProcessor类的构造函数:
public class MyProcessor : IMyProcessor
{
private readonly IFileLoader loader;
private readonly IRepository repository;
public MyProcessor(IRepository repository, string environment, Func<SysConfig, IFileLoader> loaderFactory)
{
this.repository = repository;
SysConfig config = repository.GetConfig(environment);
loader = loaderFactory(config);
}
public void DoWork()
{
loader.Process();
}
}
Run Code Online (Sandbox Code Playgroud)
这里是UnityContainer配置的Main函数:
public static void Run()
{
var unityContainer = new UnityContainer()
.RegisterType<IRepository, MyRepository>()
.RegisterType<IFileLoader, FileLoader>()
.RegisterType<IMyProcessor, MyProcessor>(new InjectionConstructor(typeof(IRepository), "DEV", typeof(Func<SysConfig, IFileLoader>)));
//Tests
var x = …Run Code Online (Sandbox Code Playgroud) I am working on a webapi project and using Unity as our IOC container. I have a set of layered dependencies something like the following:
unityContainer.RegisterType<BaseProvider, CaseProvider>(new HierarchicalLifetimeManager());
unityContainer.RegisterType<IRulesEngine, RulesEngine>();
unityContainer.RegisterType<IQuestionController, QuestionController>();
unityContainer.RegisterType<IAPIThing, WebAPIThing>();
Run Code Online (Sandbox Code Playgroud)
Now the constructor for BaseProvider accepts an int as a parameter which is the Case identifier. WebAPIThing takes a BaseProvider in its constructor. Normally in a non web scenario I would inject the case id using something like:
public static IAPIThing GetIAPIThing(int caseId)
{
return CreateUnityContainer().Resolve<IAPIThing …Run Code Online (Sandbox Code Playgroud)