1

I have a web app which is deployed on azure app service.

It has three layers.

API->Business->Data

API references assembly of Business layer ,Business layer references assembly of Data layer , (Which uses entity framework to do database transactions).

I am using Unity container to introduce dependency injection with web.config something like this.

       <unity>
<!-- lifetimes -->
<alias alias="singleton" type="Unity.Lifetime.ContainerControlledLifetimeManager, Unity.Abstractions" />
<alias alias="transient" type="Unity.Lifetime.TransientLifetimeManager, Unity.Abstractions" />
<alias alias="perThread" type="Unity.Lifetime.PerThreadLifetimeManager, Unity.Abstractions" />
<alias alias="externallyControlled" type="Unity.Lifetime.ExternallyControlledLifetimeManager, Unity.Abstractions" />

<!-- injection -->
<containers>
  <container>
    <types>
      <register type="DALContextInterface, DALInterfaceAssembly" mapTo="DALContextClass, Assembly">
        <lifetime type="perThread" />
      </register>
      <register type="BusinessLayerManagerInterface, Assembly" mapTo="BusinessLayer, Assembly">
        <lifetime type="perThread" />
        <property name="Db" dependencyType="DALContextClass, Assembly" />
      </register>
      <register type="IHomeController, Assembly" mapTo="HomeController, Assembly">
        <lifetime type="singleton" />
      </register>
    </types>
     </container>
    </containers>
   </unity>

In the controller constructor

  var _container = new UnityContainer();
  _container.LoadConfiguration();

This all works perfect in local with dependency injection.

however trouble starts when I deploy it to azure app service.

unity fails to load DALContext with the above config declaration. although Dll's are present in the AppService Bin directory.

Only after some troubleshooting did it strike me, that maybe it's because my Api project doesnt directly reference DataLayer DLL.

When i directly referred DataLayer dll in the api project, it all starts working on appservice very well.

Although it's a dirty workaround. I find it strange, that Unity can't find dll's that are not directly referenced by the api project.

Has anyone come across something like this?

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
Mandar Jogalekar
  • 3,199
  • 7
  • 44
  • 85

1 Answers1

2

Has anyone come across something like this?

XML configuration is considered to be an antiquated way to configure a DI container. This type of configuration is very brittle and provides no compile-time type checking, so it is more difficult to maintain than configuring in code. So, yes, many people have run into this and as a result changed the way they configure their container.

In this particular case, the compiler would have spotted this for you on your dev machine long before you deployed the application to the server.

When i directly referred DataLayer dll in the api project, it all starts working on appservice very well.

Although it's a dirty workaround. I find it strange, that Unity can't find dll's that are not directly referenced by the api project.

No, this is not a dirty workaround. It is normal for the assembly containing the composition root to reference all layers of the application.

Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • That’s great answer . Why does unity not detect the assemblies , even though they are in bin folder ? Albeit not directly reference by api project . Confusing . – Mandar Jogalekar Jan 25 '18 at 03:11
  • This is the same behavior as any .NET DLL - if you don't have a project reference to it, it won't load automatically. You could use `AppDomain` to load it manually, but that is more of a "dirty workaround". Although that may be the desired behavior for plugins that are uploaded after the application is deployed. – NightOwl888 Jan 25 '18 at 05:23
  • when DataLayer and BL dll's are in the bin folder at the end of publishing. how are they treated differently when unity is configured. where does it check, if BL dll is referred directly in the project but DataLayer dll isnt. maybe it's a stupid question but can't get my head around it. :) – Mandar Jogalekar Jan 25 '18 at 05:45
  • I suspect your `DataLayer` is probably referenced from a referenced project. There are a few more ways an assembly can be loaded - see [How the Runtime Locates Assemblies](https://learn.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies). – NightOwl888 Jan 25 '18 at 05:50
  • yes that's true.DataLayer is referenced from BusinessLayer project – Mandar Jogalekar Jan 25 '18 at 05:53