Strange issue I am having with my MVC3 project. I have followed a simple example of IOC using Unity.Mvc.
It works fine if my object and it's interface are in the web project itself (in this case IMessageService and MessageService). They clearly are working, no problems there.
But when I try to register my business service objects from an external assembly, they never get set to anything (always null). There are no errors in App-Start when they get registered, etc.
Anyone have any ideas? Desperate here....
UPDATE:
#Region "Imports"
Imports MyProject.Services
Imports MyProject.Services.Interfaces
Imports MyProject.Web.Mvc.Bootstrap
Imports MyProject.Web.Mvc.Services
Imports Microsoft.Practices.Unity
Imports Unity.Mvc3
#End Region
#Region "Assembly Meta"
' This tells the app to run the "Start" method prior to running the App_Start method in Global.asax
<Assembly: WebActivator.PreApplicationStartMethod(GetType(UnityDI), "Start")>
#End Region
Namespace MyProject.Web.Mvc.Bootstrap
''' <summary>
''' Class to setup dependency injection and register types/services.
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class UnityDI
''' <summary>
''' Method to register the Unity dependency injection component.
''' </summary>
''' <remarks>
''' This line of code below could alternatively be placed in Global.asax App_Start(), doing
''' so in this manner ensures that this gets run "PreStart".
''' </remarks>
Public Shared Sub Start()
' Set DI resolver
' NOTE: ECD - The UnityDependencyResolver below is part of the Unity.Mvc3 assembly
DependencyResolver.SetResolver(New UnityDependencyResolver(RegisterIocServices()))
End Sub
''' <summary>
''' Registers the IOC types/services.
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Private Shared Function RegisterIocServices() As IUnityContainer
' Create Unity dependency container
Dim dependencyContainer As IUnityContainer = New UnityContainer
' Register the relevant types/services for the container here through classes or configuration
With dependencyContainer
.RegisterType(Of IFormsAuthenticationService, FormsAuthenticationService)()
.RegisterType(Of IContactService, ContactService)()
.RegisterType(Of IProductItemService, ProductItemService)()
.RegisterType(Of ICustomerProductItemService, CustomerProductItemService)()
.RegisterType(Of ISystemTableItemService, SystemTableItemService)()
.RegisterType(Of ICatalogCodeService, CatalogCodeService)()
.RegisterType(Of IOrderService, OrderService)()
' TEST: This one is in the MVC project and works, the above are an external library
.RegisterType(Of IMessageService, MessageService)()
End With
Return dependencyContainer
End Function
End Class
End Namespace
Above code is my registration process. I have also tried putting this directly in the global.asax and have the same behavior.
UPDATE 2
Figured out my issue.
In my controller, I have the following properties:
<Dependency()>
Private Property CatalogCodeService As ICatalogCodeService
<Dependency()>
Private Property ContactService As IContactService
<Dependency()>
Private Property CustomerProductItemService As ICustomerProductItemService
But accessing the services in an action method always threw an error that there was no instance of any of these objects. So I assumed it was the original code I posted or something in there in the way I was registering.
Turns out it was not my registration code, which is perfectly fine.
The issue?
The properties have to be "Public"!! Private, Protected, Friend all do not work for IOC. Once I changed those properties to "Public", everything started working perfectly fine.
I have not verified that this is the same in C#, so if anyone can add their two cents, please by all means do so.
Go figure...
UPDATE II:
The above implementation was using public properties, which follows the "Property Injection" pattern of dependency injection.
I have since switched to the more appropriate "Constructor Injection" method.
With this change, that property for my services that my controller(s) use can be private AND read only.
"Dependency Injection in .NET" by Mark Seemann, great book. I highly suggest it for anyone implementing dependency injection or those just wanting to learn more about it.
Related
I am trying to find out how I can pass the StructrueMap container to a class that I wrote that inherits from another (MS-Class).
namespace TheNamespace
{
public class DatabaseIssuerNameRegistry : ValidatingIssuerNameRegistry
{
/* **This can't be done**
public DatabaseIssuerNameRegistry(IPortalTenantManager portalTenantManager)
{
_someField= portalTenantManager;
}*/
protected override bool IsThumbprintValid(string thumbprint, string issuer)
{
//How does it work ???????????
var portalTenantManager = container.GetInstance<IPortalTenantManager>();
//Do something with the portalTenantManager
}
}
I need portalTenantManager to be the Instance that I have defined in my container in the Global.asax.
My Global Assax has these things setup:
protected void Application_Start()
{
var container = new Container();
container.Configure(x =>
{ ....
....
x.For<IPortalTenantManager>().Use<PortalTenantManager>();
});
...
...
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory(container));
...
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapApiControllerFactory(container);
...
}
Edit:
Because of the comments of #NightOwl888 I'll explain a bit further what this class does. (Hopefully explaining so why my hands are tied)
My application is able to authenticate a user with Azure Active Directory and is Multi-tenant capable. In the authentication pipeline I have the possibility to store the validation endpoints in my database instead of the default way on the web.config file. See MSDN
and this, which actually is explaining exactly what I'm doing.
So I registered my class in the web.config under the Tag issuerNameRegistry. At some point of the validation pipeline my class is instantiated and the overriden method IsThumbprintValid is beeing called. The problem is that the class registered in issuerNameRegistry expects a parameterless constructor (there it is! the constrained construction!), therefore I cannot create a constructor that would solve my problem.
Thanks for your help
It turns out that this question has been asked before on MSDN, the answer of which was provided by Travis Spencer in 2 different posts.
it is typical in my experience to have a single container and use that service- or Web-side-wide. In the startup of the service or Web app, you can create the container, register the dependencies, new up an instance of your SecurityTokenServiceConfiguration class, resolve your dependencies, use it to punch out a SecurityTokenService object, and host it.
After the first beta, we really pushed for DI support. We got a little hook in beta 2. You can now create a custom SecurityTokenServiceConfiguration class that overrides the virtual CreateSecurityTokenService method. The implementation in Microsoft's SecurityTokenServiceConfiguration does Activator.CreateInstance; yours can do IoC. This can include the resolution of an IssuerNameRegistiry. Something like this perhaps:
RequestSecurityTokenResponse Issue(IClaimsPrincipal principal, RequestSecurityToken request)
{
SecurityTokenServiceConfiguration config = new MyGoodSecurityTokenServiceConfiguration();
SecurityTokenService sts = config.CreateSecurityTokenService();
RequestSecurityTokenResponse rstr = sts.Issue(principal, request);
return rstr;
}
public class MyGoodSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration
{
public override SecurityTokenService CreateSecurityTokenService()
{
IssuerNameRegistry = IoC.Resolve<IssuerNameRegistry>();
var sts = IoC.Reslove<SecurityTokenService>();
return sts;
}
}
Of course, this means that you need to create a static instance of your DI container so it is accessible to your SecurityTokenServiceConfiguration class. Personally, I don't like that idea because it makes your DI container accessible throughout the application, which can lead to abuse of the DI container as a service locator.
Ideally, there would be a way in any DI friendly framework to pass the container into an abstract factory in order to resolve service dependencies. However, since I am not familiar with WIF it is unclear whether that can be done - perhaps the class where the Issue method exists could have a constructor added? The trick is to keep walking up the chain until you find the first place in the framework where you can intervene and do all of your DI configuration there.
I have built an application with the dependency framework Guice. Now I will move over to OSGI and started to extend my jars with bundle information.
The main problem, which I currently face is, how to set up the dependency injection correctly. I have bundle A, which exports some packages. Then Bundle B defines a component, which needs some object (class AA) of bundle A injected.
I could set up a service for the class AA in bundle A, which will be injected automatically, but what if bundle A has also a dependency to some class in bundle A, which is maybe not exported. Do I have to set up the second class then also as service, which will not work, because it is not exported.
The following code will show the problem:
Bundle A
package test.bundleA.api
public class AA {
#Inject
public AA(AInternal someReference) {...}
}
package test.bundleA.internal
public class AInternal {...}
Bundle B:
package test.bundleB.api
public class ComponentB {
#Inject
public ComponentB(AA refToA) {...}
}
When I will use any other classes in bundle A from the exported package, do I have then to set up for each of them a service?
What is a common approach to solve the problem of dependency injection inside the bundle and even over bundle boundaries?
If you are independent of using Guice I would recommend to use Eclipse+Bndtools to create your OSGi bundles. With Bndtools, its quite easy to create OSGi bundles and also DI via Annotations. Let's take an example:
You have an interface in bundleA:
public interface Greeting {
String sayHello(String name);
}
An implementation in bundleB where #Component enables our bundle to use OSGi Declarative Service.
#Component
public class ExampleComponent implements Greeting {
public String sayHello(String name) {
return "Hello " + name;
}
}
And in the end a third bundleC where you want to us DI and inject all Greeting implementation to a specific component for usage.
#Component
public class GreetingCommand {
private Greeting greetingSvc;
#Reference
public void setGreeting(Greeting greetingSvc) {
this.greetingSvc = greetingSvc;
}
public void greet(String name) {
System.out.println(greetingSvc.sayHello(name));
}
}
As you can see with #Reference you indicate that you want to inject an implementation of your Greeting interface. The example above uses OSGi Declarative Services in combination with Bndtools. Bndtools itself takes the annotations and creates a XML file needed for OSGi to use Declarative Services. I don't want to go more deep into it. Please see [1] and [2] for more information. Just wanted to show you how DI is made by using declarative services and Bndtools.
[1] http://bndtools.org/
[2] http://wiki.osgi.org/wiki/Declarative_Services
Well, there is a extension library called Peaberry which provide integration Guice with OSGi. There is nice example how to inject a service bundle into another bundle.
Hope you will find it helpful.
The solution to your specific scenario is to define a public factory (builder) service/component that you can register with osgi and inject that type. The factory impl can be defined in the same module, and create the internal type via a 'create' or 'build' method with a return type of a public interface type, but the impl is internal.
I want to replace the default IDataBus implementation (which writes to the filesystem) with one which writes to a db (so it can run on AWS). To this end I have a config extension:
public static class ConfigureSqlServerDataBus
{
public static Configure SqlServerDataBus(this Configure config)
{
var dataBus = new SqlServerDataBus();
config.Configurer.RegisterSingleton<IDataBus>(dataBus);
return config;
}
}
to allow me to configure the bus. But obviously my SqlServerDataBus has a dependency on something which tells it where to write (An IRepository implementation in this case).
Usually I would ask for the dependency through the constructor, but as the config of the service bus is done through the IWantCustomInitialization which will use Activator to create the instance I can't. My understanding is that NServiceBus will use property injection to satisfy the dependencies but it doesn't seem to do this. I have a couple of calls like this after my configuration is done:
Configure
.With()
.DefineEndpointName("SomeName")
.DefaultBuilder()
.DBSubcriptionStorage()
.XmlSerializer()
.SqlServerDataBus()
.MsmqTransport()
.IsTransactional(true)
.UnicastBus()
.LoadMessageHandlers()
.CreateBus()
.Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
Configure.Instance.Configurer.ConfigureComponent<RepositoryImplementation>(ComponentCallModelEnum.None);
Configure.Instance.Configurer.ConfigureComponent<SqlServerDataBus>(ComponentCallModelEnum.None);
but my setters for the SqlServerDataBus are never called, although the Put method is.
Can someone point out what I'm doing wrong?
You can't change the configuration after the bus has already been started. To move your config calls into the fluent initialization code, use the RunCustomAction method.
Alternatively, you can write a new class which implements INeedInitialization and make your config calls in there. This class will be invoked at the right time.
I have been doing my first Test Driven Development project recently and have been learning Ninject and MOQ. This is my first attempt at all this. I've found the TDD approach has been thought provoking, and Ninject and MOQ have been great. The project I am working on has not particularly been the best fit for Ninject as it is a highly configurable C# program that is designed to test the use of a web service interface.
I have broken it up into modules and have interfaces all over the shop, but I am still finding that I am having to use lots of constructor arguments when getting an implementation of a service from the Ninject kernel. For example;
In my Ninject module;
Bind<IDirEnum>().To<DirEnum>()
My DirEnum class;
public class DirEnum : IDirEnum
{
public DirEnum(string filePath, string fileFilter,
bool includeSubDirs)
{
....
In my Configurator class (this is the main entry point) that hooks all the services together;
class Configurator
{
public ConfigureServices(string[] args)
{
ArgParser argParser = new ArgParser(args);
IDirEnum dirEnum = kernel.Get<IDirEnum>(
new ConstructorArgument("filePath", argParser.filePath),
new ConstructorArgument("fileFilter", argParser.fileFilter),
new ConstructorArgument("includeSubDirs", argParser.subDirs)
);
filePath, fileFilter and includeSubDirs are command line options to the program. So far so good. However, being a conscientious kind of guy, I have a test covering this bit of code. I'd like to use a MOQ object. I have created a Ninject module for my tests;
public class TestNinjectModule : NinjectModule
{
internal IDirEnum mockDirEnum {set;get};
Bind<IDirEnum>().ToConstant(mockDirEnum);
}
And in my test I use it like this;
[TestMethod]
public void Test()
{
// Arrange
TestNinjectModule testmodule = new TestNinjectModule();
Mock<IDirEnum> mockDirEnum = new Mock<IDirEnum>();
testModule.mockDirEnum = mockDirEnum;
// Act
Configurator configurator = new Configurator();
configurator.ConfigureServices();
// Assert
here lies my problem! How do I test what values were passed to the
constructor arguments???
So the above shows my problem. How can I test what arguments were passed to the ConstructorArguments of the mock object? My guess is that Ninject is dispensing of the ConstuctorArguments in this case as the Bind does not require them? Can I test this with a MOQ object or do I need to hand code a mock object that implements DirEnum and accepts and 'records' the constructor arguments?
n.b. this code is 'example' code, i.e. I have not reproduced my code verbatim, but I think I have expressed enough to hopefully convey the issues? If you need more context, please ask!
Thanks for looking. Be gentle, this is my first time ;-)
Jim
There are a few problems with the way you designed your application. First of all, you are calling the Ninject kernel directly from within your code. This is called the Service Locator pattern and it is considered an anti-pattern. It makes testing your application much harder and you are already experiencing this. You are trying to mock the Ninject container in your unit test, which complicates things tremendously.
Next, you are injecting primitive types (string, bool) in the constructor of your DirEnum type. I like how MNrydengren states it in the comments:
take "compile-time" dependencies
through constructor parameters and
"run-time" dependencies through method
parameters
It's hard for me to guess what that class should do, but since you are injecting these variables that change at run-time into the DirEnum constructor, you end up with a hard to test application.
There are multiple ways to fix this. Two that come in mind are the use of method injection and the use of a factory. Which one is feasible is up to you.
Using method injection, your Configurator class will look like this:
class Configurator
{
private readonly IDirEnum dirEnum;
// Injecting IDirEnum through the constructor
public Configurator(IDirEnum dirEnum)
{
this.dirEnum = dirEnum;
}
public ConfigureServices(string[] args)
{
var parser = new ArgParser(args);
// Inject the arguments into a method
this.dirEnum.SomeOperation(
argParser.filePath
argParser.fileFilter
argParser.subDirs);
}
}
Using a factory, you would need to define a factory that knows how to create new IDirEnum types:
interface IDirEnumFactory
{
IDirEnum CreateDirEnum(string filePath, string fileFilter,
bool includeSubDirs);
}
Your Configuration class can now depend on the IDirEnumFactory interface:
class Configurator
{
private readonly IDirEnumFactory dirFactory;
// Injecting the factory through the constructor
public Configurator(IDirEnumFactory dirFactory)
{
this.dirFactory = dirFactory;
}
public ConfigureServices(string[] args)
{
var parser = new ArgParser(args);
// Creating a new IDirEnum using the factory
var dirEnum = this.dirFactory.CreateDirEnum(
parser.filePath
parser.fileFilter
parser.subDirs);
}
}
See how in both examples the dependencies get injected into the Configurator class. This is called the Dependency Injection pattern, opposed to the Service Locator pattern, where the Configurator asks for its dependencies by calling into the Ninject kernel.
Now, since your Configurator is completely free from any IoC container what so ever, you can now easily test this class, by injecting a mocked version of the dependency it expects.
What is left is to configure the Ninject container in the top of your application (in DI terminology: the composition root). With the method injection example, your container configuration would stay the same, with the factory example, you will need to replace the Bind<IDirEnum>().To<DirEnum>() line with something as follows:
public static void Bootstrap()
{
kernel.Bind<IDirEnumFactory>().To<DirEnumFactory>();
}
Of course, you will need to create the DirEnumFactory:
class DirEnumFactory : IDirEnumFactory
{
IDirEnum CreateDirEnum(string filePath, string fileFilter,
bool includeSubDirs)
{
return new DirEnum(filePath, fileFilter, includeSubDirs);
}
}
WARNING: Do note that factory abstractions are in most cases not the best design, as explained here.
The last thing you need to do is to create a new Configurator instance. You can simply do this as follows:
public static Configurator CreateConfigurator()
{
return kernel.Get<Configurator>();
}
public static void Main(string[] args)
{
Bootstrap():
var configurator = CreateConfigurator();
configurator.ConfigureServices(args);
}
Here we call the kernel. Although calling the container directly should be prevented, there will always at least be one place in your application where you call the container, simply because it must wire everything up. However, we try to minimize the number of times the container is called directly, because it improves -among other things- the testability of our code.
See how I didn't really answer your question, but showed a way to work around the problem very effectively.
You might still want to test your DI configuration. That's very valid IMO. I do this in my applications. But for this, you often don't need the DI container, or even if your do, this doesn't mean that all your tests should have a dependency on the container. This relationship should only exist for the tests that test the DI configuration itself. Here is a test:
[TestMethod]
public void DependencyConfiguration_IsConfiguredCorrectly()
{
// Arrange
Program.Bootstrap();
// Act
var configurator = Program.CreateConfigurator();
// Assert
Assert.IsNotNull(configurator);
}
This test indirectly depends on Ninject and it will fail when Ninject is not able to construct a new Configurator instance. When you keep your constructors clean from any logic and only use it for storing the taken dependencies in private fields, you can run this, without the risk of calling out to a database, web service or what so ever.
I hope this helps.
First of all I would like to remark I am new with the concept of prism, DI and containers. I am looking on one of the code samples provided with the Prism Library:
The code simply injects a view with the "Hello World" string (in a TextBlock element) to a region in the shell.
When the application starts-up, it creates a new BootStrapper instance, which creates and initializes the shell:
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
Application.Current.RootVisual = (UIElement)this.Shell;
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
}
}
My question refers to the method CreateShell(). I couldnt find nowhere in the supplied code (including not in a configuration file or any xaml file...) where do they register the type Shell, and even if it was registered - the supplies Shell class doesnt implement any interface... what is the meaning of resolving a specific type?
the Shell implementation:
public partial class Shell : UserControl
{
public Shell()
{
InitializeComponent();
}
}
This looks like a magic to me, so I tried to create my own type (MyType) and resolve it the same way:
Container.Resolve<MyType>();
By setting a breakepoint inside MyType constructor, I saw that it DID resolved MyType. Can somebody please explain to me how does it work?
These couple of threads should answer your question:
http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=230051
Does unity just make clasess with out needing anything registered?
Additionally, if you are eager to get more detail into how Unity can do this, simple download Unity 2.0 and open the source code that is provided with the installer.
I hope this helps.
Thanks,
Damian
You do not need to register a type you want to resolve. You need to register the dependencies of a type, that you want to resolve. In this case, the Shell doesn't need any dependencies, so you can resolve it simply. But for an example (not really), if your shell getting an interface IService as a parameter, then you must register IService, before you resolve Shell.
Otherwise you will get Dependency Resolution Failed Exception. In Prism 4.1 it will be swallowed silently due to TryResolve.