Unity.NET: dependency list

Is it possible to enter a list of dependencies like this in Unity or other types of IoC libraries?

public class Crawler { public Crawler(IEnumerable<IParser> parsers) { // init here... } } 

That way I can register multiple IParser in my container and then enable them.

Is it possible? Thanks

+7
source share
5 answers

Maybe, but you need to apply some workarounds. First you need to register each IParser with a name in the Unity container. Secondly, you need to register the mapping from IParser [] to IEnumerable <IParser> in the container. Otherwise, the container cannot inject parsers into the constructor. Here is how I did it before.

 IUnityContainer container = new UnityContainer(); container.RegisterType<IParser, SuperParser>("SuperParser"); container.RegisterType<IParser, DefaultParser>("DefaultParser"); container.RegisterType<IParser, BasicParser>("BasicParser"); container.RegisterType<IEnumerable<IParser>, IParser[]>(); container.RegisterType<Crawler>(); Crawler crawler = container.Resolve<Crawler>(); 

I discarded this solution by introducing a factory that encapsulates the unit to build the necessary types. This is how I will do it in your case.

 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 Crawler { public Crawler(IParserFactory parserFactory) { // init here... } } 

With this, you can register types as follows:

 IUnityContainer container = new UnityContainer(); container.RegisterType<IParser, SuperParser>(); container.RegisterType<IParser, DefaultParser>(); container.RegisterType<IParser, BasicParser>(); container.RegisterType<IParserFactory, UnityParserFactory>(); Crawler crawler = container.Resolve<Crawler>(); 
+9
source

Not that I said it wrong, but it looks like you are trying to solve a plugin model that you could easily handle using MEF instead. Tips would be inherited by Export from interface, and then ImportMany when you need parsers.

0
source

Actually, I don’t know a container that does not support this.

However, as a general advice, you should prohibit inserting service lists into consumers, if you can, by transferring this list to composite , and introduce this composition into consumers. Not rewinding the list in the compound file clutters the application with additional foreach loops or what you need to do to process this dependency list. Although this does not seem bad, consumers of these dependencies do not care. But worse, when we want to change the way we process the list of services, we have to go through the full application, which is a violation of DRY .

This advice does not work when the consumer (in your case Crawler ) is part of the Root Composition instead of the application itself. Moreover, when the application has only one consumer that accepts this dependency, this may not be so important.

0
source

There are ways to achieve this in Unity. For example,

http://sharpsnmplib.codeplex.com/SourceControl/changeset/view/5497af31d15e#snmpd%2fapp.config

  <register type="UserRegistry"> <lifetime type="singleton" /> <constructor> <param name="users" dependencyType="User[]" /> </constructor> </register> 

This constructor requires an array of User objects, and all such objects defined in this container are injected by Unity into it when the UserRegistry object is created.

0
source

yes you can .. you can look at dependency injectors. I am a big fan of the Autofac project.

Another option is Ninject ,

-one
source

All Articles