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...