1

It seems I might have gone a bit too far with decoupling.

I have a solution with asp.net projects and I use Ninject as IoC Container.

Most of the crucial parts that are used in the MVC projects are interfaces coming from a dedicated 'Contracts' library.
The actual implementation of the interfaces are located in other assemblies, that are not really referenced directly in the MVC app. They are completely separate, MVC app only knows Contracts dll.

Ninject is loading all the referenced code in the composition root (at app startup)

 kernel.Load("MyAssPrefix.*"); //load binding modules
 kernel.Bind(x =>
        {
            x.FromAssembliesMatching("MyAssPrefix.*")
                .SelectAllClasses()
                .BindDefaultInterface();
        }); //bind all the rest

Now, the problem is that since some of the assemblies are not referenced directly in the app, then dlls are not copied to the bin folder.

This causes problems at runtime - especially difficult, considering that the type has to be called to be resolved and throw error - which means you can compile, deploy and start getting errors weeks later, when some functionality is being used.

I have a 'CompositionRoot' project which is shared among few apps and which specifies some explicit bindings. Of course this project has all the required bits added as reference, but they are not called explicitly, so they are not included.

(When I simply drop required dlls to bin folder, it starts working ok)

I have a workaround for my problem which is to have a module that could bind assemblies, where I call a random class from that assembly which causes the dll to be added to output and it all to work OK.

  public class BindAssembliesModule : NinjectModule
    {
        #region Overrides of NinjectModule
        public override void Load()
        {
            this.Kernel.Bind(x => x.FromAssembliesMatching(typeof(MyAssPrefix.SomeClass).Assembly.GetName().Name).SelectAllClasses().BindDefaultInterface());

        }
        #endregion
    }

This however seems hacky for a few reasons

  1. it is not obvious
  2. its redundant code that is not needed (except to ensure that references are not 'optiomized)
  3. its fragile - if the class that I picked is moved to a different assembly, this stops working
  4. it requires remembering about this hack when new assemblies are added

So, what is the proper way to handle that, what am I doing wrong?

Bartosz
  • 4,406
  • 7
  • 41
  • 80

2 Answers2

0

I've had this problem in the past. The way i've got around it is to add a reference to the projects/dlls concerned. MsDeploy will ignore them as they aren't actually used in code, just reference referenced, so they get left behind as you have seen.

Then what I did was follow something like the methodology in this answer: adding extra files to published MVC API project

Which allows you to pick up extra files from the bin folder and get them into the publish stage.

It's a one time fix for the host project and then you can forget about it, it will work fine afterwards.

Slicksim
  • 7,054
  • 28
  • 32
0

You can avoid these hacks by:

  • Create a post-build event in your start-up project and write here a command copying all your dll dependencies to your output folder
  • Write your custom build script and do the same here
Jan Muncinsky
  • 4,282
  • 4
  • 22
  • 40