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.
Related
I wish to inject a service into a custom class i have created> i have been using Dependency injection to inject the same service into my WebApi controllers but cannot seem to understand why it doesn't work in my "InputDataValidationModel" class
This is what i am trying to do:
public class InputDataValidationModel
{
private ISec300_EE_SubmissionRepository _service { get; set; }
public InputDataValidationModel(ISec300_EE_SubmissionRepository service)
{
_service = service;
}
}
In the Global.asax i registered the types as follow:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureApi(GlobalConfiguration.Configuration);
}
void ConfigureApi(HttpConfiguration config)
{
var unity = new UnityContainer();
// Register the Controllers that should be injectable
unity.RegisterType<SEC300_EE_SubmissionController>();
unity.RegisterType<InputDataValidationModel>();
unity.RegisterType<ISec300_EE_SubmissionRepository, Sec300_EE_SubmissionRepository>(new ContainerControlledLifetimeManager());
unity.RegisterType<IClientRepository, ClientRepository>(new ContainerControlledLifetimeManager());
// Finally, override the default dependency resolver with Unity
config.DependencyResolver = new IoCContainer(unity);
}
What I cant understand specifically is that this works perfectly when done in my controller below:
public class SEC300_EE_SubmissionController : ApiController
{
private ISec300_EE_SubmissionRepository _service;
public SEC300_EE_SubmissionController(ISec300_EE_SubmissionRepository service)
{
if (service == null)
{
throw new ArgumentNullException("service");
}
_service = service;
}
}
It does not work because controllers are instantiated by Web API, and when Web API creates a controller it calls BeginScope which is the entry point to call your IoC and proceeds to resolve and constructs objects for you.
In your case InputDataValidationModel is not used and may be for this reason you don't have the instance
update
Do you perhaps have any suggestions on how i would inject my service into InputDataValidationModel ?
Option 1
You can use IDependencyResolver take a look at this link Dependency Resolution with the Unity Container`'
And after this you can resolve your service like this
var instance =GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof (InputDataValidationModel));
Option 2
You might use service locator even it is an anti-pattern
static void Main(string[] args)
{
UnityServiceLocator locator = new UnityServiceLocator(ConfigureUnityContainer(
ServiceLocator.SetLocatorProvider(() => locator);
var a = ServiceLocator.Current.GetInstance<IFoo>();
var b = ServiceLocator.Current.GetInstance<IFoo>();
Console.WriteLine(a.Equals(b));
}
private static IUnityContainer ConfigureUnityContainer()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager());
return container;
}
Hope this help
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.
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();
}
}
}
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
I have a Windows service where I use OWIN and NancyFX to host a website on top of it. On many places in my service, I use Unity to inject dependencies into classes, mostly services. However, if I use them in any Nancy modules, the dependencies get resolved twice because Nancy uses its own IoC container (TinyIoC).
Fortunately, Nancy allows to override the default IoC container generation and use of an existing one by creating a nancy bootstrapper. But how do I pass my existing IUnityContainer to the bootstrapper?
Basically, all I have to start OWIN is...
WebApp.Start<MyOwinStarter>(url);
How can I pass a Unity container to it to pass it further to the nancy bootstrapper?
#ccellar got me into the right direction.
I created a static class UnityHelper with the following methods:
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => {
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unityConfiguration");
return new UnityContainer().LoadConfiguration(section);
});
public static IUnityContainer GetConfiguredContainer() {
return container.Value;
}
Created a custom NancyBootstrapper class:
public NancyBootstrapper(IUnityContainer container) {
if(container == null)
throw new ArgumentNullException("container");
this._unityContainer = container;
}
protected override IUnityContainer GetApplicationContainer() {
return _unityContainer;
}
and passed the container to the bootstrapper in my web app startup class:
appBuilder.UseNancy(new NancyOptions {
EnableClientCertificates = true,
Bootstrapper
= new NancyBootstrapper(UnityHelper.GetConfiguredContainer())
});
Neat!
Disclaimer: I really don't know if this is the best/cleanest/whatever solution to this problem. But for me it works.
I wrapped my container (Castle Windsor) like this, which is basically a singleton.
public class Container
{
// static holder for instance, need to use lambda to construct since constructor private
private static readonly Lazy<IWindsorContainer> instance = new Lazy<IWindsorContainer>(() =>
{
var container = new WindsorContainer();
container.Install(FromAssembly.This());
return container;
});
// private to prevent direct instantiation.
private Container()
{
}
// accessor for instance
public static IWindsorContainer Instance
{
get
{
return instance.Value;
}
}
}
Then in my custom bootstrapper I access the already configured container like this
protected override Castle.Windsor.IWindsorContainer GetApplicationContainer()
{
return Container.Instance;
}
Actually, the easiest and correct way, would be to inherit a new bootstrapper class from the Bootstrapper type you are using - in your case WindsorNancyBootstrapper and override the GetApplicatioContainer method and return your instance
You can read more about it here
https://github.com/NancyFx/Nancy.bootstrappers.windsor#customizing