3

I was developing an application. I want unity to resolve my types WITHOUT having to reference the assemblies in the main project. I tought it loaded assemblies automatically by configuring the type registration by using but doesn't seem to work unless I add a reference to the assembly containing dependencies.

Is there a wat to load types from the assemblies in the current directory?

Thanks!

Satish
  • 3,020
  • 7
  • 35
  • 47
Luis Aguilar
  • 4,331
  • 6
  • 36
  • 55

3 Answers3

4

Sounds like you want MEF and not Unity. MEF is designed for dynamic discovery.

Read the answer to this question: What is different between and purpose of MEF and Unity?

Community
  • 1
  • 1
ErnieL
  • 5,773
  • 1
  • 23
  • 27
3

I know this was asked a while ago, but for anyone looking for an answer, you have to make sure that Unity can locate the assemblies at run-time. So you either need to put them in the GAC or drop your assembly dll in the same directory as your executable. If you are using a different directory for dependencies and have a web app, then you have to set the probing element in your web.config:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Dependencies" />
    </assemblyBinding>
</runtime>

And for anyone out there looking for a piece of code on how to solve this, the following code will look for all assemblies on your defined directory and register them with Unity:

string DependenciesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Dependencies");
string[] Dependencies   = Directory.GetFiles(DependenciesPath, DLL_PATTERN);

Dictionary<Type, Type> pluginMappings = new Dictionary<Type, Type>();

//Load Dependency Assemblies
foreach (string fileName in Dependencies)
{
    string assemblyName = Path.GetFileNameWithoutExtension(fileName);
    if (assemblyName != null)
    {
        Assembly pluginAssembly = Assembly.Load(assemblyName);

        foreach (Type pluginType in pluginAssembly.GetTypes())
        {
            if (pluginType.IsPublic) //Only look at public types
            {
                if (!pluginType.IsAbstract)  //Only look at non-abstract types
                {
                    //Gets a type object of the interface we need the plugins to match
                    Type[] typeInterfaces = pluginType.GetInterfaces();
                    foreach (Type typeInterface in typeInterfaces)
                    {
                        if (pluginMappings.ContainsKey(typeInterface))
                        {
                            throw new DuplicateTypeMappingException(typeInterface.Name, typeInterface, pluginMappings[typeInterface], pluginType);
                        }
                        pluginMappings.Add(typeInterface, pluginType);
                    }
                }
            }
        }
    }
}

//Web API resolve dependencies with Unity
IUnityContainer container = new UnityContainer();
foreach (var mapping in pluginMappings)
{
    container.RegisterType(mapping.Key, mapping.Value);
}
Alberto Rechy
  • 145
  • 1
  • 12
0

It might be a bit late to help, but Unity can dynamically load assemblies if you use the XML configuration approach, register each assembly, and then register the types accordingly. I've been using this process for minor extensions to an otherwise very DI-heavy framework for awhile now.

If you're encountering an issue where Unity fails to resolve a type that's registered in the main application but defined in another, unreferenced assembly and referencing said assembly resolves the issue, that most likely means that it just wasn't copied to the application's output directory. By default, only assemblies that are directly referenced are automatically copied. If they're copied manually or by a post-build event, or if you redirect your build paths so that the unreferenced assemblies build to the application's output directory, it should work.

William Scalf
  • 422
  • 2
  • 13