我正在开发一个项目,其中Unity框架用作IoC容器.我的问题涉及使用property-或setter注入将可选依赖项(在本例中为记录器)注入到几个类中.
我不想使用这些可选的依赖项来混乱所有类的构造函数,但是我找不到在Unity中处理它的好方法.根据MSDN文档,您可以通过向属性添加属性来实现此目的:
private ILogger logger;
[Dependency]
public ILogger Logger
{
get { return logger; }
set { logger = value; }
}
Run Code Online (Sandbox Code Playgroud)
我觉得这很难看.在StructureMap中,可以执行以下操作来设置给定类型的所有属性:
SetAllProperties(policy => policy.OfType<ILog>());
Run Code Online (Sandbox Code Playgroud)
有谁知道在Unity中是否有可能做类似的事情?
编辑:
Kim Major建议使用这种方法,也可以通过代码实现.
我会对如何自动为所有匹配属性执行此操作的示例感兴趣.
我终于忍受了Dependency Injection(早就应该); 我开始玩Unity并遇到战略模式的问题.我可以使用容器向我返回基于名称的策略的特定实现,但我没有看到我应该如何在上下文中获得正确的策略.
让我们举一个简单的例子说明:上下文是一辆汽车,它有一个IEngine(策略),有2个实现,FastEngine和SlowEngine.代码将沿着这些方向看:
public interface IEngine
{
double MaxSpeed
{
get;
}
}
internal class FastEngine:IEngine
{
public double MaxSpeed
{
get
{
return 100d;
}
}
}
internal class SlowEngine:IEngine
{
public double MaxSpeed
{
get
{
return 10d;
}
}
}
public class Car
{
private IEngine engine;
public double MaximumSpeed
{
get
{
return this.engine.MaxSpeed;
}
}
public Car(IEngine engine)
{
this.engine = engine;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题如下:我应该如何实例化快车或慢车?我可以使用容器为我提供每个实现,我可以设置一个"默认"实现来使用:
IUnityContainer container = new UnityContainer();
container.RegisterType<IEngine, FastEngine>();
container.RegisterType<IEngine, FastEngine>("Fast"); …Run Code Online (Sandbox Code Playgroud) c# dependency-injection ioc-container unity-container strategy-pattern
我正在使用Unity IoC容器.这真的不是我做出的决定,它只是与Prism一起来的,我只是坚持下去.我从未使用任何其他IoC框架,我必须承认我对Unity非常满意.然而,满意度可能来自无知,因为我不知道其他框架提供了什么.
我一直听说我不应该使用Unity IoC容器.人们说,"使用Castle,nInject或StructureMap",但我仍然没有听到任何具体的论据或例子,为什么我应该使用不同的框架.那么,为什么我不应该使用Unity?或许我应该?
我有一个看起来像这样的代码.当ResolveAll我试图做一个 我期望IParserType从容器实例中产生的所有注册的类型.但我没有得到任何实例Unity.我在这里假设或做错了什么.
public class ResolveAllDemo
{
public ResolveAllDemo()
{
var container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);
container.RegisterType<IParser, SuperParser>();
container.RegisterType<IParser, DefaultParser>();
container.RegisterType<IParser, BasicParser>();
// container.RegisterType<Crawler>();
container.RegisterType<IParserFactory, UnityParserFactory>();
foreach (var registeredMember in container.ResolveAll<IParser>())
{
LoggingUtility.LogerInstance.Logger.Write(registeredMember);
}
}
#region Resolve Demo
public interface IParserFactory
{
IEnumerable<IParser> BuildParsers();
}
public class UnityParserFactory : IParserFactory
{
private IUnityContainer _container;
public UnityParserFactory(IUnityContainer container)
{
_container = container;
}
public IEnumerable<IParser> BuildParsers()
{
return _container.ResolveAll<IParser>();
}
}
public class DefaultParser : IParser …Run Code Online (Sandbox Code Playgroud) 我正在尝试将Unity包添加到我的解决方案中,但我一直收到列出的消息:
试图解决依赖'Unity(≥3.5.1404.0)'.
'Unity'已经为'CommonServiceLocator'定义了依赖关系.
任何想法如何解决这个问题?
如果您不知道我在说什么,请查看教程并尝试自己添加依赖注入,或者尝试一下我对问题的解释.
注意:此问题不在ASP.NET原始教程的范围内.本教程仅建议使用的模式是依赖注入友好的.
问题基本上是Controller,ModelStateWrapper和ContactManagerService之间存在依赖循环.
所以依赖循环是这样的:Controller> Service> ModelStateWrapper> Controller
如果您尝试向此添加依赖项注入,它将失败.所以我的问题是; 我该怎么办呢?其他人已经发布了这个问题,但答案很少,不同,所有看起来都有点"黑客".
我目前的解决方案是从IService构造函数中删除IModelStateWrapper并添加一个Initialize方法,如下所示:
public class ContactController : Controller
{
private readonly IContactService _contactService;
public ContactController(IContactService contactService)
{
_contactService = contactService;
contactService.Initialize(new ModelStateWrapper(ModelState));
}
//Class implementation...
}
public class ContactService : IContactService
{
private IValidationDictionary _validationDictionary;
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
private void Initialize(IValidationDictionary validationDictionary)
{
if(validationDictionary == null)
throw new ArgumentNullException("validationDictionary");
_validationDictionary = validationDictionary; …Run Code Online (Sandbox Code Playgroud) asp.net-mvc dependency-injection inversion-of-control unity-container
我刚刚将我的ASP.NET MVC/WebApi项目从Microsoft.Practices.Unity 3.5.1404升级到3.5.1406(通过nuget,刚刚发布).之后,我收到了这个编译错误:
错误CS0012类型"IUnityContainer"在未引用的程序集中定义.您必须添加对程序集"Microsoft.Practices.Unity,Version = 3.0.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35"的引用.
在如下的行上:
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
Run Code Online (Sandbox Code Playgroud)
当然,我没有引用3.0.0.0,而是3.5.1.0.所以我的假设是Unity.WebApi程序集已针对程序集的早期版本进行编译Microsoft.Practices.Unity.从理论上讲,您需要使用程序集重定向来修复它,如下所示:
<dependentAssembly>
<assemblyIdentity name="Microsoft.Practices.Unity" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.1.0" newVersion="3.5.1.0" />
</dependentAssembly>
Run Code Online (Sandbox Code Playgroud)
但是,这似乎不起作用.
有什么建议?
我正在使用Web.api和Unity,我在尝试打开默认的"帮助"区域时收到以下错误:
[InvalidOperationException: The type String cannot be constructed. You must configure the container to supply this value.]
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.GuardTypeIsNonPrimitive(IBuilderContext context, SelectedConstructor selectedConstructor) +280
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context) +356
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260
Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey) +205
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +231
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260
Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250
Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101
BuildUp_System.Web.Http.HttpRouteCollection(IBuilderContext ) +202
Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +319
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260
Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250
Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) +101
BuildUp_System.Web.Http.HttpConfiguration(IBuilderContext ) +202
Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) +42
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) +319
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) +260
Microsoft.Practices.ObjectBuilder2.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey) +250
Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context) …Run Code Online (Sandbox Code Playgroud) architecture dependency-injection inversion-of-control unity-container asp.net-web-api
我是使用Unity的新手,但我的问题是每当我调用我的Web服务时,我都会得到一个例外情况
"确保控制器具有无参数的公共构造函数"
我已经遵循了多个教程,我仍然遇到同样的问题.
在我的WebApiConfig类的Register函数中,我有
var container = new UnityContainer();
container.RegisterType<IValidator, Validator>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
Run Code Online (Sandbox Code Playgroud)
这是我的UnityResolver类
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException) …Run Code Online (Sandbox Code Playgroud) 最终这与设置log4Net有关,但一般来说问题不是特定于日志记录.
一般来说,我想弄清楚的是在Microsoft Unity 2.0中,如何做到与Castle.Facilities.Logging.LoggingFacility相同的东西.即能够声明对记录器的依赖性并使用其注入的对象的Type初始化记录器.
本着考试的精神值得千言万语,这就是我所需要的:
class Logger_IOC_Tests
{
//[Test]
public void Logger_should_be_initialized_with_the_type_of_the_object_that_is_using_it()
{
var container = new UnityContainer();
/* Configuration Magic probably involiving registering either
* a custom IDependencyResolverPolicy or BuilderStrategy
* goes here...
*/
container.RegisterType<LoggerUser>(new ContainerControlledLifetimeManager());
var user = container.Resolve<LoggerUser>();
Assert.True(user.Logger.GetUserType() == user.GetType());
}
}
interface ILogger
{
Type GetUserType();
}
class Logger : ILogger
{
private readonly Type _type;
public Logger(Type type)
{
_type = type;
}
public Type GetUserType()
{
return _type;
}
}
class LoggerUser
{ …Run Code Online (Sandbox Code Playgroud) c# log4net dependency-injection castle-windsor unity-container
unity-container ×10
c# ×6
.net ×2
architecture ×1
asp.net ×1
asp.net-mvc ×1
log4net ×1
nuget ×1