Reputation: 1759
I have a web service (let's call it WebSite
) that uses an Interface (IDataService
). the webservice project implements a "fake" service with hardcoded objects (DesignDataService
) that I use to develop the websit while I wait for my colleagues to build the real implementation (BreadDataService
).
My NinjectWebCommon is currently like this:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IDataService>().To<DesignDataService>();
}
What I want is to be able to provide my colleague a way to test the BreadDataService
on my WebService, while I can go on using DesignDataService
. I can't use the BreadDataService
on my machine because it requires some assemblies that I don't have (+ the database).
So, what is the approach here? The current dependency tree is like that:
ServiceCore
(defines IDataService
)WebSite
uses ServiceCore
BreadDataService
uses ServiceCore
I don't want to reference the BreadDataService
project inside the WebSite
Project, I was maybe thinking about a folder in WebSite
where they can put the BreadDataService
dll and ninject takes it depending on some configuration in web.config.
Hints?
Upvotes: 0
Views: 643
Reputation: 1759
I used qujck approach to build these extension methods.
The main difference is that it relies on Ninject.Extensions.Conventions
' FromAssembliesInPath
method
Upvotes: 1
Reputation: 14580
Something like this will do the trick
Here's the basic code
IEnumerable<Assembly> assemblies = this.LoadAssemblies(@"C:\Temp");
Type implementation = FindImplementation(assemblies, typeof(IDataService));
IKernel kernel = new StandardKernel();
kernel.Bind<IDataService>().To(implementation ?? typeof(DesignDataService));
This method will load external assemblies (such as plugins) from a specific folder
private IEnumerable<Assembly> LoadAssemblies(string folder)
{
IEnumerable<string> dlls =
from file in new DirectoryInfo(folder).GetFiles()
where file.Extension == ".dll"
select file.FullName;
IList<Assembly> assemblies = new List<Assembly>();
foreach (string dll in dlls)
{
try
{
assemblies.Add(Assembly.LoadFile(dll));
}
catch
{
}
}
return assemblies;
}
And this method will search a set of assemblies for an implementation. Please note that I have specifically used SingleOrDefault()
so that this will fail if there is more than one implementation.
private Type FindImplementation(
IEnumerable<Assembly> assemblies,
Type serviceType)
{
var implementationType = (
from dll in assemblies
from type in dll.GetExportedTypes()
where serviceType.IsAssignableFrom(type)
where !type.IsAbstract
where !type.IsGenericTypeDefinition
select type)
.SingleOrDefault();
return implementationType;
}
Upvotes: 2