How to resolve UnityContainer and when in windows serivce - c#

I am creating a Windows Service which uses existing class library for application and domain models.
Application layer already have already defined ContainerConfig which registers all Interfaces like
public class ConfigContainer
{
public UnityContainer ContainerConfig()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IAttachmentService, AttachmentService>(new ContainerControlledLifetimeManager());
container.RegisterType<IBrxxgeService, BrxxgeService>(new ContainerControlledLifetimeManager());
container.RegisterType<ICaxxxxociationService, CaxxxxociationService>(new ContainerControlledLifetimeManager());
container.RegisterType<ITraxxxacityService, TraxxxcityService>(new ContainerControlledLifetimeManager());
return container;
}
}
There are more than 30 Service Interfaces registered here like that. in Window Service Program.cs
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new DClearanceService()
};
ServiceBase.Run(ServicesToRun);
}
Then in DClearanceService.cs
public partial class DClearanceService : ServiceBase
{
private ConfigContainer _containerConfig = new ConfigContainer();
private UnityContainer _container = new UnityContainer();
public DimensionalClearanceService()
{
InitializeComponent();
ExceptionHandlingManager.InitializeExceptionManager();
_container = _containerConfig.ContainerConfig();
}
Inside my methods are resolving container:
public class EMTrocessor
{
_clRequestService = Container.Resolve<IClRequestService>();
public bool ProcessMessage(string message)
{
List<ClOutput> clOutputs = _clRequestService.GetClOutputs();
}
}
If I run this code using visual studio in debugger mode, it works fine but when I run this windows service, I get Microsoft.Practices.Unity.ResolutionFailedException
<Description>An exception of type 'Microsoft.Practices.Unity.ResolutionFailedException' occurred and was caught.</Description>
<DateTime>2015-11-30 16:53:55Z</DateTime>
<ExceptionType>Microsoft.Practices.Unity.ResolutionFailedException, Microsoft.Practices.Unity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f</ExceptionType>
<Message>Resolution of the dependency failed, type = "CPR.Apps.Application.Interfaces.IClEventService", name = "(none)".
Exception occurred while: Calling constructor CPR.Apps.Application.Services.CleranceEventService().
Exception is: ResolutionFailedException - Resolution of the dependency failed, type = "CPR.Apps.Domain.Interfaces.IClEventManager", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, CPR.Apps.Domain.Interfaces.IClEventManager, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving CPR.Apps.Domain.Interfaces.IClEventManager,(none)
When I call service, it already resolves the related service and this is how visual studio interact with db and returns the result. Why it can't do the same when I run Windows Service?
My question is:
how do I resolve this issue? Do I need to add
_attachmentService = Container.Resolve<IAttachmentService>();
_brxxgeService = Container.Resolve<IBrxxgeService>();
_clRequestService = Container.Resolve<IClRequestService>();
for all of the interface services here?
if yes, where should I add them?
Please help.

Better way to use continer extensions:
public class ModelContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IAttachmentService, AttachmentService>(new ContainerControlledLifetimeManager());
Container.RegisterType<IBrxxgeService, BrxxgeService>(new ContainerControlledLifetimeManager());
Container.RegisterType<ICaxxxxociationService, CaxxxxociationService>(new ContainerControlledLifetimeManager());
Container.RegisterType<ITraxxxacityService, TraxxxcityService>(new ContainerControlledLifetimeManager());
}
}
public partial class DClearanceService : ServiceBase
{
private UnityContainer _container = new UnityContainer();
public DimensionalClearanceService()
{
InitializeComponent();
ExceptionHandlingManager.InitializeExceptionManager();
_container.AddExtension(new ModelContainerExtension());
}
Why it's better? In your case you replace whole container variable, and if you made some registraions before - you'll lose it. With AddExtension you'll add new registrations to existing ones.

Related

Web API - Inject dependency at ServiceContainer using Unity

I am using ExceptionLogger to handle all the global exception. My inheriting class requires dependencies to be injected for Nlog to invoke.
public class NLogExceptionLogger : ExceptionLogger
{
private readonly ILoggingService _loggingService;
public NLogExceptionLogger(ILoggingService<NLogExceptionLogger> loggingService)
{
_loggingService = loggingService;
}
public override void Log(ExceptionLoggerContext context)
{
_loggingService.FirstLevelServiceLog(context.Exception.StackTrace);
}
}
LoggingService Class:
public class LoggingService<T> : ILoggingService<T>
{
private readonly ILogger _logger;
public LoggingService()
{
string currentClassName = typeof(T).Name;
_logger = LogManager.GetLogger(currentClassName);
}
public void FirstLevelServiceLog(string log)
{
_logger.Log(LogLevel.Debug, log);
}
}
My Unity Code:
public static UnityContainer RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType(typeof(ILoggingService<>), typeof(LoggingService<>))
}
I am registering ExceptionLogger globally by doing: (On this line i am getting an error)
config.Services.Add(typeof(IExceptionLogger), typeof(NLogExceptionLogger));
//Register Dependency Container
config.DependencyResolver = new UnityDependencyResolver(UnityConfig.RegisterComponents());
I am getting following error at runtime:
System.ArgumentException: 'The type RuntimeType must derive from IExceptionLogger.'
My assumption is i am not properly registering the dependency for NLogExceptionLogger.
Any idea on how to resolve dependency while registering the service?
When adding service to ServicesContainer you add the type with the service instance.
Assuming dependency resolver has already been setup, that can be used to resolve the instance if it has dependencies.
var logger = config.DependencyResolver.GetService(typeof(NLogExceptionLogger));
config.Services.Add(typeof(IExceptionLogger), logger);
There is also a difference between exceptions loggers and exception handlers.
I suggest reviewing the following reference link to determine which one is appropriate for your needs.
Reference Global Error Handling in ASP.NET Web API 2

IFacebookManager, is an interface and cannot be constructed. Are you missing a type mapping?

I tried to do something like login with facebook in xamarin forms but i have Excpetion in constructor while app is loading
This is my code
private readonly INavigationService _navigateService;
private readonly IFacebookManager _facebookManager;
private readonly IPageDialogService _dialogService;
and In Constructor
public LoginPageViewModel(INavigationService navigationService, IPageDialogService dialogService , IFacebookManager facebookManager)
{
_dialogService = dialogService;
_facebookManager = facebookManager;
_navigateService = navigationService;
IsLogedIn = false;
}
but i got this exception and i don't know why
Unity.Exceptions.ResolutionFailedException: Resolution of the dependency failed, type = 'System.Object', name = 'LoginPage'.
Exception occurred while: Calling constructor LGMobileApp.Views.LoginPage().
Exception is: ResolutionFailedException - Resolution of the dependency failed, type = 'LGMobileApp.ViewModels.LoginPageViewModel', name = '(none)'.
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, LGMobileApp.Helpers.IFacebookManager, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving LGMobileApp.ViewModels.LoginPageViewModel,(none)
Resolving parameter 'facebookManager' of constructor LGMobileApp.ViewModels.LoginPageViewModel(Prism.Navigation.INavigationService navigationService, Prism.Services.IPageDialogService dialogService, LGMobileApp.Helpers.IFacebookManager facebookManager)
Resolving LGMobileApp.Helpers.IFacebookManager,(none)
-----------------------------------------------
At the time of the exception, the container was:
Resolving LGMobileApp.Views.LoginPage,LoginPage (mapped from System.Object, LoginPage)
Resolving LGMobileApp.Views.LoginPage,LoginPage
Calling constructor LGMobileApp.Views.LoginPage()
In my app.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<LoginPage>();
}
Any help ?
While Prism does ensure that each container will resolve a concrete type for you as this is required to resolve your ViewModel, none of the containers can resolve an interface without a registration.
Any implementation that is available in your shared code can be done in your App.RegisterTypes like:
public class App : PrismApplication
{
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IFacebookService, FacebookService>();
}
}
If your implementation type is platform specific then you would need to add something like this to each of your platform projects like iOS, Android, etc.
public class PlatformInitializer : IPlatformInitializer
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IFacebookService, FacebookService>();
}
}
Then when you load your app you would pass this into the ctor like:
new App(new PlatformInitializer())
Note that there are a couple of different ways to register a service. The one shown above registers the service as a transient so each time it is requested you will get a new instance. You can also call RegisterSingleton or RegisterInstance (if you have already created an instance) to get the same instance across your app

WCF : Passing parameter to ServiceHost

Hi I'm working with framework 4.0, Ioc Microsoft Practice Unity
In the main program I load all services when create a service I have two parameters
(IUnitOfWork unitOfWork,IRepository<Persona> personaRepository)
in this case.
In the main program how can I pass these two the parameters to the ServiceHost when creating it?
ServiceHost host = new ServiceHost(service)?
Service:
public class RegService : IRegService
{
private IUnitOfWork unitOfWork;
private IRepository<Persona> personaRepository;
public RegService(IUnitOfWork unitOfWork,IRepository<Persona> personaRepository){
this.unitOfWork = unitOfWork;
this.personaRepository = personaRepository;
}
public IEnumerable<Persona> ListaPersonas(){
return personaRepository.GetAll();
}
public int PersonaInsert(Persona oPersona){
personaRepository.Add(oPersona);
return oPersona.IdPersona;
}
}
Main:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting services...");
Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ServiceModelSectionGroup serviceModel = ServiceModelSectionGroup.GetSectionGroup(appConfig);
ServiceElementCollection serviceSection = serviceModel.Services.Services;
foreach (ServiceElement objService in serviceModel.Services.Services){
Type service = Type.GetType(objService.Name + ", Mistic.Contador.Services.Implementation");
{
ServiceHost host = new ServiceHost(service);
host.Open();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Service started: " + objService.Endpoints[0].Contract);
}
}
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("Services are ready... Press enter to close the services.");
Console.ReadLine();
}
}
When I execute in this line host.Open() I have this message:
The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.
Update Bootstrap (Unity)
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();
string connectionString = "ModelMovieSolContainer";container.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager(), new InjectionConstructor(connectionString));
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<>));
container.BindInRequestScope<IMovieService, MovieService>();
return container;
}
}
You can create an own ServiceHost implementation to provide the ability of injecting dependencies into your srvices but i recommend to use an existing container for that.
For exemple Ninject has a great WCF support and it is easy to use. The built in NinjectServiceHostFactory can create it's own ServiceHost so you dont need to create it manually. All you have to is to register a Kernel with the NinjectServiceHostFactory.SetKernel() (and the dependencies of course).
I'm usually create a derived type from NijectServiceHostFactory and register the Kernel in the constructor of it with the modules but in a self hosted application you can do it some other way.

Unity DI on a Windows Service, Is possible?

I am developing a Windows Service to do some periodical operations, can I use Unity to inject my classes from another library there?
I want to use with the [Dependency] attribute on my services, registering the components on the entry point of the windows service start.
Example:
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
UnityConfig.RegisterComponents();
ServicesToRun = new ServiceBase[]
{
new EventChecker()
};
ServiceBase.Run(ServicesToRun);
}
}
public static class UnityConfig
{
public static void RegisterComponents()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IEventBL, EventBL>();
}
}
public partial class EventChecker : ServiceBase
{
private Logger LOG = LogManager.GetCurrentClassLogger();
[Dependency]
public Lazy<IEventBL> EventBL { get; set; }
protected override void OnStart(string[] args)
{
var events = EventBL.Value.PendingExecution(1);
}
}
In this scenario the EventBL is always null, so is not resolved by the [Dependency] of unity. There aren't a way to make it working?
Thanks!
Solution Found:
After write the answer I found a possible solution, calling to build up method of the container to create the service class works:
UnityContainer container = new UnityContainer();
UnityConfig.RegisterComponents(container);
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
container.BuildUp(new EventChecker())
};
ServiceBase.Run(ServicesToRun);
If you know any other solution, please share it :)
A DI Container like Unity can just as well be used to compose the object graphs of Windows Services. Note that in general you should prefer using constructor injection. This prevents temporal coupling and prevents your code to have a dependency on the DI library itself (which is quite ironic to have need dependency on the DI library, since it's trying to help you preventing strong coupling between components).
Furthermore, you should simply let the container resolve your services. In other words, don't new up your services by hand, but request a new instance from the container:
ServicesToRun = new ServiceBase[]
{
container.Resolve<EventChecker>()
};
But do note that your EventChecker is resolved once and stored for the duration of the application. That effectively makes it a singleton and with that all its dependencies will becomes singletons. So instead, it's better to make your ServiceBase implementation part of the composition root and resolve new instances from the container every time your time fires:
public class EventChecker : ServiceBase
{
private static IUnityContainer container;
public EventChecker(IUnityContainer container)
{
this.container = container;
}
public void SomeOperationThatGetsTriggeredByATimer()
{
using (var scope = this.container.BeginLifetimeScope())
{
var service = scope.Resolve<IEventCheckerService>();
service.Process();
}
}
}

using a Handler in Web API and having Unity resolve per request

I am using Unity as my IoC framework and I am creating a type based on the value in the header of each request in a handler:
var container = new UnityContainer();
container.RegisterType<IFoo,Foo>(new InjectionConstructor(valuefromHeader));
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
The problem is that the handler's SendAsync means that the global container is getting overwritten by different requests and the controllers that use IFoo in their constructor are getting the wrong values.
1) Can I make the SendAsync sync?
2) If not, how do I create different instances for each request and have the IoC container resolve safely?
I have looked at the following articles without success:
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
http://www.strathweb.com/2012/11/asp-net-web-api-and-dependencies-in-request-scope/
http://benfoster.io/blog/per-request-dependencies-in-aspnet-web-api-using-structuremap
Thanks in advance.
I agree with #Steven's approach, but that doesn't answer your more general question of how to resolve per request.
I would recommend you change to using the UnityHierarchicalDependencyResolver and then anything you register with HierarchicalLifetimeManager will be resolved per request.
Change this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(container);
to this...
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityHierarchicalDependencyResolver(container);
The problem you are having is caused by you mixing runtime values with design time dependencies. In general, the services you resolve from the container should not depend on runtime values in their constructor. You shouldn't do this, because components tend to live much longer than runtime values and injecting runtime values into components, makes it much harder to diagnose and verify the container's configuration.
Instead, hide that value behind a service that can provide consumers with that instance when required. For instance:
public interface IHeaderValueProvider
{
HeaderValue GetCurrentValue();
}
You can create an implementation that can be easily registered and injected into any component that needs that value. Anytime after the construction phase, those components can call the GetCurrentValue() method on the injected IHeaderValueProvider dependency.
I managed to resolve per request by declaring my custom UnityResolver's class within the WebApiConfig class. The UnityResolver class uses the HttpConfiguration class assuming you're using an OWIN context.
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var _container = new UnityContainer();
DependencyConfiguration.ConfigureContainer(_container);
config.DependencyResolver = new UnityResolver(_container);
}
The ConfigureContainer class is simply a class where I declare my IOC dependencies as shown below:
private static void RegisterReleaseEnv(IUnityContainer container)
{
//Repository Registration
container
.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>), new HierarchicalLifetimeManager());
}
It is very important that you use the HierarchicalLifetimeManager lifetime manager so that you get a new instance per request.
The UnityResolver class then looks like this:
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
I hope this helps.
For more information: http://www.asp.net/web-api/overview/advanced/dependency-injection

Categories

Resources