Reputation: 21
I am working on WPF/MVVM application, which is sort of an expansion of functionality for another desktop application (let us call it Application X). I am trying to use layered approach with multiple projects covering different concerns: presentation, infrastructure, application etc.
It uses external DLL library with API to application X. Once in a while there is a new major version of application X released together with new version of DLL library. Library is referenced in all projects with "Copy Local No"
setting. Proper version of library is loaded dynamically from application X installation path, based on user selection at app start, using assembly resolve event AppDomain.CurrentDomain.AssemblyResolve
. This solution is proposed by library provider in their documentation. There was no issue with this approach until now.
Service interface is defined in project AppName.Application
, which has properties of type from external library:
using Library.DLL;
namespace AppName.Application.FeatureX
{
public interface IService
{
TypeFromLibrary PropertyX { get; }
}
}
Concrete implementation of this service is placed in separate project AppName.Infrastructure
:
using Library.DLL;
namespace AppName.Infrastructure.FeatureX
{
public class Service : IService
{
TypeFromLibrary PropertyX { get; }
}
}
I am using dependency injection container from Microsoft.Extensions.DependencyInjection
, with service registration at app startup with Microsoft.Extensions.Hosting
.
services.TryAddSingleton<Service>();
services.TryAddSingleton<IService>(sp => sp.GetRequiredService<Service>());
Order of actions at startup is as follows:
At app startup following exception is thrown, just before the call of method registering service into DI container:
System.IO.FileNotFoundException: Could not load file or assembly 'Library.DLL, Version=x.x.x.x, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxx' or one of its dependencies. The system cannot find the file specified
I have tried to find, what is the real problem and I can't find anything online on such specific situation. I have tried the following just to debug the issue:
1. Remove IService registration
Runtime error at registration is thrown.
2. Remove Service registration
Runtime error at registration disappears, but obviously service is not resolved. It seems there is no issue with registering interface, but there is one with registering implementation. I don't see the connection.
3. Place IService/Service in the same project
Runtime error at registration disappears. Why does service registration requires the assembly to be loaded, when interface/implementation are in two different projects and why it doesn't happen, when they are in the same project ? This is not a solution for me, as I want to have a clear separation for contracts, which application layers is using and the implementation of service.
I could build host after assembly selection, but I don't want to, because assembly selection view communicates with application layer via ViewModel with dependency injected services. Is there anything that must be setup at configuration level ?
Upvotes: 2
Views: 193