Unity, Prism, FSharp - f#

I get a resolve error when I try to inject into a FSharp library but not wen I do so with a CSharp library.
I have 3 projects :
A main application in csharp
A CSharp project containing a class whose constructor requires a IUnityContainer that gets instantiated fine
A FSharp project containing a class whose constructor requires a IUnityContainer that can't instantiate with error
Resolution of the dependency failed, type =
"ModuleDBGraphFS.ModuleEntityGraphFS", name = "(none)". Exception
occurred while: while resolving. Exception is:
InvalidOperationException - The current type,
Microsoft.Practices.Unity.IUnityContainer, is an interface and cannot
be constructed. Are you missing a type mapping?
At the time of the exception, the container was:
Resolving ModuleDBGraphFS.ModuleEntityGraphFS,(none) Resolving
parameter "container" of constructor
ModuleDBGraphFS.ModuleEntityGraphFS(Microsoft.Practices.Unity.IUnityContainer
container, Microsoft.Practices.Prism.Regions.IRegionManager manager)
Resolving Microsoft.Practices.Unity.IUnityContainer,(none)
Application class in the 1st project (WPF project, you add prism, remove the startupuri from app.xaml, add on the code behind for the bootstrapper )
namespace WpfApplication
{
class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return this.Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
App.Current.MainWindow = (Window)this.Shell;
App.Current.MainWindow.Show();
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
// OK moduleCatalog.AddModule(typeof(ModuleDBGraph.ModuleEntityGraph));
// KO moduleCatalog.AddModule(typeof(ModuleDBGraphFS.ModuleEntityGraphFS));
}
}
}
In the C# project
public class ModuleEntityGraph : IModule
{
private IUnityContainer _container;
private readonly IRegionManager _manager;
public ModuleEntityGraph(IUnityContainer container, IRegionManager manager)
{
_container = container;
_manager = manager;
}
void IModule.Initialize()
{
}
}
in the F# project
type ModuleEntityGraphFS(container:IUnityContainer, manager:IRegionManager) =
do printfn "hi"
interface Microsoft.Practices.Prism.Modularity.IModule with
member x.Initialize() =
do ()

For some reason, the Nuget script for prism added reference in my module project to
C:\windows\assembly\GAC_MSIL\Microsoft.Practices.Unity\1.2.0.0__31bf3856ad364e35\Microsoft.Practices.Unity.dll
While the shell project itself was referencing
WpfApplication3\packages\Unity.2.1.505.2\lib\NET35\Microsoft.Practices.Unity.dll
A fresh solution that I started made me see the problem.
Hence the odd message that it could not resolve UnityContainer itself (which should be registered somewhere by Prism Unity extensions....)

Related

Ioc registering error: The current type is an interface and cannot be constructed. Are you missing a type mapping?

I am writing an ASP.NET MVC code and I try to implement inversion of control via Microsoft Unity.
I follow the document above:
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection
Here is my project structure:
Model
Presentation
Repository
Service
Web
Web can only sees Presentation. Presentation can only sees Service. Here is my Bootstrapper.cs file in Web Layer.
public static class Bootstrapper
{
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
container.RegisterType<IButcePresenter, ButcePresenter>();
container.RegisterType<IProjeFaaliyetPresenter, ProjeFaaliyetPresenter>();
container.RegisterType<ISektorPresenter, SektorPresenter>();
container.RegisterType<IProjePresenter, ProjePresenter>();
container.RegisterType<IFaaliyetPresenter, FaaliyetPresenter>();
container.RegisterType<IKurumCografyaLokasyonPresenter, KurumCografyaLokasyonPresenter>();
container.RegisterType<IVeriSaglayici, VeriSaglayici>();
return container;
}
}
I call the Bootstrapper class inside Global.asax.cs as such:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
Bootstrapper.Initialise();
}
}
Here is my main controller:
public class ErpController : Controller
{
//
private readonly IButcePresenter _butcePresenter;
private readonly IProjeFaaliyetPresenter _iProjeFaaliyetPresenter;
private readonly ISektorPresenter _sektorPresenter;
private readonly IProjePresenter _projePresenter;
private readonly IFaaliyetPresenter _faaliyetPresenter;
private readonly IKurumCografyaLokasyonPresenter _kurumCografyaPresenter;
private readonly IVeriSaglayici _veriSaglayici;
private readonly CevirmeIslemleri _cevirmeIslem;
public ErpController(IButcePresenter butcePresenter, IProjeFaaliyetPresenter projeFaaliyetPresenter,
ISektorPresenter sektorPresenter, IProjePresenter projePresenter, IFaaliyetPresenter faaliyetPresenter, IKurumCografyaLokasyonPresenter kurumCografyaPresenter, IVeriSaglayici veriSaglayici)
{
this._butcePresenter = butcePresenter;
this._iProjeFaaliyetPresenter = projeFaaliyetPresenter;
this._sektorPresenter = sektorPresenter;
this._projePresenter = projePresenter;
this._faaliyetPresenter = faaliyetPresenter;
this._kurumCografyaPresenter = kurumCografyaPresenter;
this._veriSaglayici = veriSaglayici;
this._cevirmeIslem = new CevirmeIslemleri();
}
}
Here is my IButcePresenter. It is defined at the Presentation layer.
public class ButcePresenter : IButcePresenter
{
private readonly IButceServis _butceServis;
private readonly IYetkiServis _yetkiServis;
private readonly IProjeFaaliyetServis _projeFaaliyetServis;
private readonly Cevirme _cevir = null;
private readonly KontrolIslemleri _kontrolIk = null;
public ButcePresenter(IButceServis butceServis, IYetkiServis yetkiServis, IProjeFaaliyetServis projeFaaliyetServis)
{
this._butceServis = butceServis;
this._yetkiServis = yetkiServis;
this._projeFaaliyetServis = projeFaaliyetServis;
this._cevir = new Cevirme();
this._kontrolIk = new KontrolIslemleri();
}
public ButcePresenter()
{
//TODO: Fools man injection
this._butceServis = new ButceServis();
this._yetkiServis = new YetkiServis();
this._projeFaaliyetServis = new ProjeFaaliyetServis();
this._cevir = new Cevirme();
this._kontrolIk = new KontrolIslemleri();
}
}
I can not define IButceServis 's concrete defition in Unity, because, IButceServis and its concrete implementation ButceServis is at the Service layer. Web layer can not see Service layer. I am getting
The current type, DKMPPIB.Presentation.Soyut.IButcePresenter, is an
interface and cannot be constructed. Are you missing a type mapping?
How can I solve the issue? Could you please any clue? Thanks in advance.
Investigations:
I have investigate these questions and they do not help:
The current type is an interface and cannot be constructed. Are you missing a type mapping?
It asks me a create controller factory. So I did. It does not work.
Exception is: InvalidOperationException - The current type, is an interface and cannot be constructed. Are you missing a type mapping?
It misuse the DI concept, so it does not fit my case.
The current type, is an interface and cannot be constructed. Are you missing a type mapping?
He forgets registering the concrete class.
I have found a solution. I cannot initialize the classes inside the class library independently. When the web layer sees all layers, say Model,Presentation,Repository and Service and when all interfaces has been instantiated in web layer, it works. Main thing that we should understand here is interfaces inside the class libraries cannot be initialized inside class library.

Ninject + WCF Issue

I'm trying to use Ninject with a WCF service of mine. I'm using Ninject 2.2.1.4 and Ninject.Extensions.Wcf 2.2.0.4. My unit test to ensure Ninject is working properly fails with an ArgumentNullException; Parameter root: null.
Here is my code:
//A couple of classes to setup ninject and its bindings
public class NinjectBindings : NinjectModule
{
public override void Load()
{
Bind<IEmployeeRepository>().To<SqlEmployeeRepository>().InSingletonScope();
}
}
public class Global : NinjectWcfApplication
{
protected override IKernel CreateKernel()
{
IKernel kernel = new StandardKernel(new NinjectBindings());
return kernel;
}
}
//Test method that fails with ArgumentNullException
[TestMethod]
public void Should_Be_Able_To_Get_Employee_Service_From_Ninject()
{
Global globalService = new Global();
var kernel = globalService.Kernel;
EmployeeService employeeService = kernel.Get<EmployeeService>();
Assert.IsNotNull(employeeService);
}
After creating Global you have to initialize it properly by calling Application_Start() and Init() as IIS would do. After this your integration test should run.
But be aware that in reality kernel.Get is not triggered directly as you do in your test. The creation of the service is much more complex.
When using Ninject.Wcf, your Global doesnt get newd as you've done - you tell WCF that the factory for creating Global is ~NinjectWcfHostFactory, which triggers the CreateKernel() that's not happening in your context.
The example shows the overriding of the factory (in a propery on the service declaration within the .svc file).

Problems integrating nServiceBus with StructureMap

I'm trying to use StructureMap with nServiceBus.
The Project:
Uses a GenericHost Endpoint to send command messages
Configures nServiceBus using the StructMapBuilder.
Uses a simple StructureMap registry config
Uses a start up class TestServer supporting IWantToRunAtStartup
The TestServer class has ctor dependency on a TestManager class
The TestManager class has ctor dependency on IBus
ObjectFactory.WhatDoIHave() shows StructureMap knows how to construct the classes.
When run I get buildup errors. nServiceBus seems to be overwriting the config?
Note that when I add a IBus ctor depenendency to my event handlers without any other config all appears fine.
Error:
Exception when starting endpoint, error has been logged. Reason: Error creating object with name 'nSeviceBusStructureMapTest.TestServer' : Unsatisfied dependency expressed through constructor argument with index 0 of type [nSeviceBusStructureMapTest.ITestManager] : No unique object of type [nSeviceBusStructureMapTest.ITestManager] is defined : Unsatisfied dependency of type [nSeviceBusStructureMapTest.ITestManager]: expected at least 1 matching object to wire the [miningServiceManage] parameter on the constructor of object [nSeviceBusStructureMapTest.TestServer]
Source:
using System;
using System.Diagnostics;
using NServiceBus;
using StructureMap;
using StructureMap.Configuration.DSL;
namespace nSeviceBusStructureMapTest
{
public class TestSmRegistry : Registry
{
public TestSmRegistry()
{
For<ITestManager>().Use<TestManager>();
For<TestServer>().Use<TestServer>();
}
}
public class TestEndPoint : AsA_Server, IConfigureThisEndpoint
{
public void Init()
{
Configure.With().StructureMapBuilder(ObjectFactory.Container);
ObjectFactory.Configure(c => c.AddRegistry<TestSmRegistry>());
Debug.WriteLine(ObjectFactory.WhatDoIHave());
}
}
public class TestServer : IWantToRunAtStartup
{
public TestServer(ITestManager miningServiceManage)
{
_miningServiceManage = miningServiceManage;
}
private readonly ITestManager _miningServiceManage;
public void Run()
{
_miningServiceManage.Run();
}
public void Stop() { }
}
public interface ITestManager
{
void Run();
}
public class TestManager : ITestManager
{
public TestManager(IBus bus)
{
_bus = bus;
}
private readonly IBus _bus;
public void Run()
{
if (_bus == null) Debug.WriteLine("Error no bus");
// Send messages on bus;
}
}
}
<MsmqTransportConfig InputQueue="test" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig>
<MessageEndpointMappings>
</MessageEndpointMappings>
</UnicastBusConfig>
Any ideas?
You have to specify IWantCustomInitialization on the endpoint config class. Otherwise NServiceBus won't call the Init() method. You also need to specify what serializer to use so add:
Configure.With()
.StructureMapBuilder()
.XmlSerializer();
Hope this helps!

Registering NUnit DynamicMock Instances in a UnityContainer

I'm somewhat new to Unity and dependency injection. I'm trying to write a unit test that goes something like this:
[Test]
public void Test()
{
UnityContainer container = new UnityContainer();
DynamicMock myMock = new DynamicMock(typeof(IMyInterface));
container.RegisterInstance(typeof(IMyInterface), myMock.MockInstance); //Error here
// Continue unit test...
}
When this test executes, the container throws an ArgumentNullException inside the RegisterInstance method with the message Value cannot be null. Parameter name: assignmentValueType.
The top line of the stack trace is at Microsoft.Practices.Unity.Utility.Guard.TypeIsAssignable(Type assignmentTargetType, Type assignmentValueType, String argumentName).
Why can't I register a MockInstance with the UnityContainer, and how do I work around this?
I'm not seeing this. I'm using NUnit 2.5.5.10112 and Unity 2.0 (which ships with EntLib, the separate release isn't available just yet).
Update: I just checked with 1.2 and I see your behavior. So this is an issue with 1.2.
namespace UnityRepro
{
public interface IMyInterface
{
void Foo();
}
public class Class1
{
[Fact]
public void Test()
{
UnityContainer container = new UnityContainer();
DynamicMock myMock = new DynamicMock(typeof(IMyInterface));
container.RegisterInstance(typeof(IMyInterface), myMock.MockInstance); //Error here
Assert.NotNull(container.Resolve<IMyInterface>());
}
}
}
Would it be possible for you to update to Unity 2.0? If not I'll try and dig deeper and find out what's really going on. This may be a limitation of 1.2 though.

Why does my Ninject DI application fail with an ActivationException?

I'm new to IoC/DI frameworks. The first one I am trying is the Ninject framework. It seems straightforward, but I can't get my console application to run. I keep getting an ActivationException stating:
"Error activating MainWindow: the StandardProvider returned an instance of type FutureRealisticDateManager, which is not compatible with the requested service.
Using default binding from MainWindow to FutureRealisticDateManager (via StandardProvider)
declared by DateBindingModule.Load()
Activation path:
1) active request for MainWindow
from Program.Main()
using default binding from MainWindow to FutureRealisticDateManager (via StandardProvider)
declared by DateBindingModule.Load()"
My code is very simple. Here is my Program file...
class Program
{
static void Main(string[] args)
{
IKernel k = new StandardKernel(new DateBindingModule());
MainWindow mw = k.Get<MainWindow>();
mw.Show();
Console.ReadLine();
}
}
Here is my ninject binding module...
public class DateBindingModule : StandardModule
{
public override void Load()
{
Bind<MainWindow>().To<FutureRealisticDateManager>();
}
}
Here is the class that receives the injected class...
class MainWindow
{
private IRealisticDateManager _d;
[Inject]
public MainWindow(IRealisticDateManager dateManager)
{
_d = dateManager;
}
public void Show()
{
Console.WriteLine("*** MainWindow [" + _d.GetRealisticDate().ToString() + "] ");
}
}
And here is the actual class being injected...
public class FutureRealisticDateManager : TestNinject.IRealisticDateManager
{
public DateTime GetRealisticDate()
{
return DateTime.Now.AddDays(15);
}
}
And finally the simple interface that the injected class should implement...
public interface IRealisticDateManager
{
DateTime GetRealisticDate();
}
Can anybody see what I am doing wrong?
It fails because your binding is not right:
Bind<MainWindow>().To<FutureRealisticDateManager>();
FutureRealisticDataManager does not inherit from MainWindow.
Instead you should write:
Bind<IRealisticDateManager>().To<FutureRealisticDateManager>();
This tells Ninject to return FutureRealisicDateManager whenever IRealisicDateManager is requested.
This way when you call k.Get<MainWindow>() kernel will inject FutureRealisticDateManager to the constructor.

Resources