给出以下界面:
public interface IMyProcessor
{
void Process();
}
Run Code Online (Sandbox Code Playgroud)
我希望能够注册多个实现并让我的DI容器将其中的可枚举注入到这样的类中:
public class MyProcessorLibrary
{
private readonly IMyProcessor[] _processors;
public MyProcessingThing(IMyProcessor[] processors)
{
this._processors = processors;
}
public void ProcessAll()
{
foreach (var processor in this._processors)
{
processor.Process();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?我当前MyProcessorLibrary的IMyProcessor实现静态查找所有实现,但如果可以的话,我宁愿通过容器来实现.我正在使用Unity,但我很好奇其他容器是否支持它.
编辑:
谢谢你到目前为止的答案; 要清楚我想注入MyProcessorLibrary另一个类,并将其构建为依赖对象树的连接的一部分,例如
public class MyProcessorRepository
{
public MyProcessorRepository(MyProcessorLibrary processorLibrary)
{
}
}
public class MyProcessorService
{
public MyProcessorService(MyProcessorRepository processorRepository)
{
}
}
var container = new UnityContainer();
// Register a bunch of IMyProcessors... …Run Code Online (Sandbox Code Playgroud) 我在Silverlight 5项目中有一个IValueConverter实例,它将自定义数据转换为不同的颜色.我需要从数据库中读取实际的颜色值(因为这些可以由用户编辑).
由于Silverlight使用异步调用通过Entity Framework从数据库加载数据,因此我创建了一个简单的存储库,它保存数据库中的值.
界面:
public interface IConfigurationsRepository
{
string this[string key] { get; }
}
Run Code Online (Sandbox Code Playgroud)
实施:
public class ConfigurationRepository : IConfigurationsRepository
{
private readonly TdTerminalService _service = new TdTerminalService();
public ConfigurationRepository()
{
ConfigurationParameters = new Dictionary<string, string>();
_service.LoadConfigurations().Completed += (s, e) =>
{
var loadOperation = (LoadOperation<Configuration>) s;
foreach (Configuration configuration in loadOperation.Entities)
{
ConfigurationParameters[configuration.ParameterKey] = configuration.ParameterValue;
}
};
}
private IDictionary<string, string> ConfigurationParameters { get; set; }
public string this[string key]
{
get
{
return ConfigurationParameters[key];
}
} …Run Code Online (Sandbox Code Playgroud) c# ioc-container unity-container ivalueconverter silverlight-5.0
class Entity:IEntityName
{
#region IEntityName Members
public string FirstName { get; set; }
public string LastName { get; set; }
#endregion
}
public class Person:IPerson
{
public IEntityName EntityName;
public Person()
{
}
public Person(IEntityName EntityName)
{
this.EntityName = EntityName;
}
public string ReverseName()
{
return string.Format("Your reverse name is {0} {1}",EntityName.LastName, EntityName.FirstName);
}
public override string ToString()
{
return string.Format("Name is {0} {1}", EntityName.FirstName, EntityName.LastName);
}
}
// Main Method
private static string DisplayReverseName(string fName,string lName)
{
IUnityContainer container …Run Code Online (Sandbox Code Playgroud) 我正在使用Unity.WCF为WCF服务注入依赖项.将服务设置为时出现问题InstanceContextMode.Single.
我在谷歌上发现,当InstanceContextMode设置为时Single,InstanceProvider不会被调用.还有一个解决方法,但我想知道在Unity.WCF中是否有一些内置的支持,因为这显然是一个众所周知的问题.
我在这里找到了这些信息:启用InstanceProvider单例服务.
说,我有以下项目结构:
Application <-> BusinessLogic <-> DataAccessLayer
Run Code Online (Sandbox Code Playgroud)
我已准备好使用穷人依赖注入的所有类型,现在我想用Unity引入真正的类型.但是我在努力放置依赖容器及其配置的位置(我想我会从代码中配置它).
目前,使用容器实际实例化类的唯一程序集将是Application.所以我有以下依赖关系图:
我在这里有循环引用,所以将DI放在Application中似乎是合法的.但是我必须引用DataAccessLayer,这是我不想创建的依赖项.我该如何解决这个问题?
我已经碰到了围绕各个网站提出的一些问题,答案似乎是由l4n officianados转向了log4net'是'的轻量级包装器的价值(你不明白吗?)和类似的观点令人难以置信的事实.
然而,似乎用户要求的(这是我的问题)是如何使log4net objet模型适应fluent配置界面中的registertype/registerinstance序列.
这里的目标不是重新包装l4n,而只是为了获得一个不需要劫持流畅流量的体面参考,就像它一样.
糟糕的ejemplow,我想从LogManger.GetLogger方法获得对已配置的ILog实例的引用,并将其尽早放入流体流中,以将其注入我的下游对象的属性中.
因此,为了回应一个不耐烦的建议,我尝试以规范的方式创建了一个正常的ILog实例:
log4net.Config.XmlConfigurator.Configure();
static readonly log4Net.Ilog Log = LogManager.GetLogger(thatlongassemblyreflectionstuff);
Run Code Online (Sandbox Code Playgroud)
因此,现在将这个引用添加到Unity容器并继续我的美好生活似乎是微不足道的(在真正意义上毫不费力).
但是,RegisterInstance方法的签名需要"类型"而不是接口.
对于那些没有搜索过log4net对象模型的人来说,afficiananderos是正确的:l4n是一个"包装器",你无法得到Log thingie的实际"类型".
所以现在我必须测试.你知道这意味着什么,它可能需要一分钟,但更可能需要一个小时或四个(类似于'小时'和'四'的拼写在现实生活中从来不是巧合).
但是,以下内容除了关于规范设置的省略部分外,确实有效:
container
.RegisterInstance("Logger", Log, new ContainerControlledLifetimeManager())
.RegisterType<IControllerContext, ControllerContext>
(
"CtlrCtx",
new ContainerControlledLifetimeManager(),
new InjectionConstructor(new ResolvedParameter<IMessageBuilder>("MsgBldr")),
new InjectionProperty("Log",new ResolvedParameter<ILog>("Logger"))
);
Run Code Online (Sandbox Code Playgroud)
因此,原始Log对象的哈希码和注入到我的marvy小对象对象的属性中的Log对象是相同的.
然而...
注入过程要求我通过其接口公开Context对象的Log属性,这意味着它不再是静态对象.并且log4net ILog对象是否是静态的似乎是决定它是否可序列化并且可以在程序集之间进行编组而没有戏剧性的"运行时将变得不稳定"警告(这对于Matrix粉丝来说真正有意义).
气馁,虽然没有阻止,但我使用Resharper的漂亮'带有支持字段的属性'并将支持字段设置为静态,而Interface属性保持非静态.它建成了,测试运行绿色.
所以我甚至进行了重建并且有效.所以也许当这个泡沫达到集成测试时,我会偷偷溜过log4net,这不是可序列化的崩溃.
所以也许这会有所帮助
谢谢
Stato
如何在Unity中注册和解析通用对象/接口?我试图远离配置文件.
我正在寻找类似的东西
IEnterpriseClient<IInterface1> 解决 EnterpriseClient<IInterface1>
班级签名是
class EnterpriseClient<T> : IEnterpriseClient<T> where T : class
Run Code Online (Sandbox Code Playgroud)
谢谢!
鉴于此类:
class Foo
{
readonly ILog log;
public Foo(ILog log)
{
this.log = log;
}
...
}
Run Code Online (Sandbox Code Playgroud)
我想配置Unity注入ILog.这很简单:
container.RegisterInstance<ILog>(LogManager.GetLogger(typeof(XYZ)));
Run Code Online (Sandbox Code Playgroud)
但是我想LogManager.GetLogger用正在解析的父类型的类型进行Unity调用.
这很接近:
container.RegisterType<ILog>(new InjectionFactory((c, t, s) => LogManager.GetLogger(t)));
Run Code Online (Sandbox Code Playgroud)
但t在这种情况下,类型是resolve(ILog),而不是为(Foo)解析对象的类型.
我知道我可以这样做:
container.RegisterType<Foo>(new InjectionFactory(c => new Foo(LogManager.GetLogger(typeof(Foo)));
Run Code Online (Sandbox Code Playgroud)
但是我不希望每次注册对象时都要添加那个疯狂的声明.
我知道这可以在Autofac中完成,我知道真正的答案不是首先使用Unity,但这可以做到吗?:)
我们通常只在我们的应用程序中引用Microsoft.Practices.Unity.dll.我们只使用基本功能,这很好用.在一个应用程序中,使用反射的行为导致Unity需要另一个DLL.
例如,创建一个控制台应用程序并仅引用Microsoft.Practices.Unity(文件版本2.0.414.0).输入以下代码并运行它:
class Program
{
static void Main()
{
using (var container = new UnityContainer())
{
container.RegisterType<IDoSomething, ConcreteDoSomething>();
var thing = container.Resolve<IDoSomething>();
thing.DoSomething();
Console.WriteLine();
LoadSchemaLoaders();
}
}
public static void LoadSchemaLoaders()
{
var type = typeof(ISchemaLoader);
try
{
// Get all loaded assemblies, including Unity.
// Get all of the types.
// Filter for types that ISchemaLoader (custom type) can be assigned from.
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(c => type.IsAssignableFrom(c) && c.IsClass && !c.IsAbstract && !c.IsGenericParameter);
Console.WriteLine("Got …Run Code Online (Sandbox Code Playgroud) 我在Unity中注册了几种类型,并给出了类型别名,如下所示:
<typeAliases>
<typeAlias alias="MyType" type="foo.bar.MyType, foo.bar" />
</typeAliases>
Run Code Online (Sandbox Code Playgroud)
是否可以使用别名(而不是类型)从容器中解析这些类型,顺序如下:
var myType = container.ResolveByTypeAlias("MyType")
Run Code Online (Sandbox Code Playgroud)
我看不出有什么方法可以做到这一点,但我想知道我是否错过了什么.