Using Unity / Bootstrapper, I'm registering my base class - ServiceBase to multiple concrete services.
container.RegisterType<ServiceBase, ClearedPaymentService>("ClearedPaymentService");
container.RegisterType<ServiceBase, MissedPaymentService>("MissedPaymentService");
I'm also registering an external service below this:
container.RegisterType<IPaymentService, PaymentServiceClient>("PaymentService");
The external service is used in both the ClearedPaymentService and MissedPaymentService as shown below:
public partial class ClearedPaymentService : ServiceBase
{
private readonly IPaymentService _paymentService;
private readonly IScheduler _scheduler;
private Timer _timer;
public ClearedPaymentService(IPaymentService paymentService, IScheduler scheduler)
{
_paymentService = paymentService;
_scheduler = scheduler;
}
...etc
}
When I come to use my 2 services, I run into trouble:
var container = (IUnityContainer)Bootstrapper.Container;
var services = container.ResolveAll<ServiceBase>();
if (Environment.UserInteractive)
{
RunInteractive(services.ToArray());
}
The code throws an exception on "services.ToArray()":
Resolution of the dependency failed, type = "System.ServiceProcess.ServiceBase", name = "ClearedPaymentService".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, Think.IncomeProtection.ThirdParty.Service.Contract.Outbound.IPaymentService, is an interface and cannot be constructed. Are you missing a type mapping?
At the time of the exception, the container was:
Resolving ThirdPartyPaymentInvoker.ClearedPaymentService,ClearedPaymentService (mapped from System.ServiceProcess.ServiceBase, ClearedPaymentService)
Resolving parameter "paymentService" of constructor ThirdPartyPaymentInvoker.ClearedPaymentService(Think.IncomeProtection.ThirdParty.Service.Contract.Outbound.IPaymentService paymentService, ThirdPartyPaymentInvoker.IScheduler scheduler)
Resolving Think.IncomeProtection.ThirdParty.Service.Contract.Outbound.IPaymentService,(none)
I understand what the error is saying - the constructor of ClearedPaymentService is expecting a concrete instance of IPaymentService, but it hasn't been resolved for some reason...
I'm fairly new to Unity, so presume it's something basic that I haven't understood yet!
Any help appreciated.
Thanks,
Alex
Your registrations to container provide a name for each service that is registered. So basically there is no default (not named) service that Unity can use in your scenario.
To fix this just remove the names while registering thins. If on other hand you wish to use specific named service then there is an attribute that you can add on parameter of your constructor [NamedDependancy("Your name")]. But by default you should not use this feature the code is simpler without it.
Related
New to Simple Injector, trying to get some pieces working for a prototype. I am creating a WPF application that uses Simple Injector and ReactiveUI, but can't seem to get explicit property injection via attribute to trigger. The specific example I am working through is just testing injection of a logger. The plan is to roll this into a decorator, but I have run across the need for attribute injection with previous projects/DI libraries. Just want to verify I am able to use it.
Snippet of the bootstrapping:
private Container RegisterDependencies(Container container = null)
{
container ??= new Container();
// Container initialization that must precede dependency registration
// occurs here
// Enable property injection via the [Import] attribute
container.Options.PropertySelectionBehavior =
new ImportPropertySelectionBehavior();
SimpleInjectorInitializer initializer = new SimpleInjectorInitializer();
Locator.SetLocator(initializer);
Locator.CurrentMutable.InitializeSplat();
Locator.CurrentMutable.InitializeReactiveUI();
container.UseSimpleInjectorDependencyResolver(initializer);
container.RegisterConditional(
typeof(ILogger),
c => typeof(NLogLogger<>)
.MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
container.Register<MainWindow>();
container.Register<ISystem, System>(Lifestyle.Singleton);
container.Verify();
return container;
}
An instance of the System is requested from the DI container in the static RunApplication called from Main:
var system = container.GetInstance<ISystem>();
And here is the property injection in the system:
public class System : ISystem
{
[Import] public ILogger Logger { get; set; }
public System()
{
// Logger is null here. NullReferenceException is thrown
Logger.LogInfo("Creating System");
}
}
At this point in the constructor, the Logger property is null and attempt to log fails with exception. I should mention the ILogger is my own abstraction of NLog. If I instead perform constructor injection:
public System(ILogger logger)
Simple Injector picks up on this and resolves the dependency fine. I have tried changing the Import attribute to a different custom-defined Dependency attribute, no change. Have also tried just instantiating the logger as a singleton, same behavior.
Really appreciate any ideas, I'm running dry on searching forums, the SimpleInjector/ReactiveUI docs, and Steven's DI book.
Edit - here is the PropertySelectionBehavior code as well:
public class PropertySelectionBehavior<T> : IPropertySelectionBehavior
where T : Attribute
{
public bool SelectProperty(
Type implementationType, PropertyInfo propertyInfo) =>
propertyInfo.GetCustomAttributes(typeof(T)).Any();
}
public class ImportPropertySelectionBehavior :
PropertySelectionBehavior<ImportAttribute> { }
2nd Edit - I can take out all of the initialization related to ReactiveUI and still reproduce same behavior. New sample looks like:
private Container RegisterDependencies(Container container = null)
{
container ??= new Container();
container.Options.PropertySelectionBehavior =
new ImportPropertySelectionBehavior();
// Logger registration
container.RegisterConditional(
typeof(ILogger),
c => typeof(NLogLogger<>)
.MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
// UI registration
container.Register<MainWindow>();
//container.Register<MainWindowViewModel>();
container.Register<ISystem, System>(Lifestyle.Singleton);
container.Verify();
return container;
}
You are using the Logger property from inside System's constructor. Properties, however, are only initialized after the constructor finished. If you remove Simple Injector from the equation, and fallback to plain old C#, you would see the same. For instance:
var system = new System() // <-- constructor call
{
Logger = new NLogLogger<System>() // Logger_set is called after the ctor
};
If you run this code, you will see the same NullReferenceException thrown by the constructor of System.
What this means is that you shouldn't use any properties from inside your constructor. Even more broadly, from a DI perspective, you shouldn't use any service inside your constructor (or during construction for that matter) as is described by Mark Seemann here.
Update, the explicit property injection is working fine. It occurs after construction. I imagine there are design reasons for this, although somehow it was contrary to my mental model that the property injection would be performed on-demand/on first use.
Planning on experimenting a bit more to see what control is available over the timing to resolve property dependencies. If anyone who is more experienced has any advice on that or can point me to additional documentation I would welcome it. The decorator sounds like the more elegant way to make sure the logger is available as expected and allow independent lazy loading of decoratee concerns. Some discussion here:
SimpleInjector - "Lazy" Instantiate a singleton that has dependencies on first use
I use AutoFac. I have to resolve a type with an explicit instance which I get from another service.
For example: I have an instance of type Client which I get from somewhere (not from the container).
I want to configure the Autofac container so that always when an object of type Client should be resolved, it should return my instance.
Problem is that I don't have this instance at the time, when I configure the container with the Containerbuilder - so I cannot use for example LambdaRegistration.
Is there another solution for solving my problem?
You can do the following:
MyService service = null;
builder.Register(c => service).As<IMyService>();
// Later on
service = new MyService();
Depending on your needs there are quite some variations of this approach possible, such as:
Send a 'setter' delegate to some initialization code that will call the delegate after the service gets created, e.g. MyServiceInitializer.AfterInitialization(s => service = s);
Promote the service variable to a class property and provide that new wrapper to the initialization
Hide access to the service behind specific read and write abstractions, e.g. interface IMyServiceContext { IMyService Current { get; } } and interface IMyServiceSetter { void SetCurrent(IMyService service); }.
Prevent Autofac from accidentally resolving the service before it is initialized by throwing an exception instead of throwing null, e.g. Register(c => service ?? throw new InvalidOperationException("..."))
It's important to note, however, that in general, the creation of components should be fast and reliable. The fact that your component isn't available at startup is likely because it requires I/O to setup. This is a situation should should try to prevent, for instance by hiding it behind an abstraction completely. This allows you to implement a Proxy that allows the real service to be lazy loaded.
Hopefully this gives you some clues on how to solve this.
I am using .NET Core dependency injection, but when I am trying to get the service in another class, I am getting the 'IServiceProvider.GetService(Type)' cannot be used with type arguments' error.
What does this error means?
I understand that a generic type argument is something like this: GenericInterface<>, and the GetService method does not take the GenericInterface<> as an argument.
Why am I getting this error and how do I solve it?
The interface
public interface IService
{
void Process();
}
The class implementing the interface
public class Service : BaseService<IConfig, SomType>
{
public Service(
ILogger logger : base(logger)
{
}
...
}
The BaseService class is an abstract class and it implements the IService interface.
public abstract class BaseService<TConfig, TE> : AnotherBaseService, IService where TConfig : IConfig where TE : struct, IConvertible
{
protected BaseService(ILogger logger): base(logger)
{
}
...
}
The AnotherBaseService
public abstract class BaseService
{
protected readonly ILogger Logger;
protected BaseService(ILogger logger)
{
Logger = logger;
}
...
}
How I registered them.
serviceCollection.AddScoped<IService, Service>();
How I am getting the service I need.
var incoming = serviceProvider.GetService<IService>();
NB: I am just getting started with dependency injection, .NET Core and do not know everything about DI just yet. Your answers would be of great help.
The generic GetService< T> method is an extension method. This means you need to have a :
using Microsoft.Extensions.DependencyInjection;
to allow the compiler to find it.
This method is only meant for optional services. It will return null if the object can't be constructed, either because the type wasn't registered or because some of its dependencies are missing.
GetRequiredService should be used when an application can't work unless a service is available. If an instance can't be created, it will throw an InvalidOperationException.
When that exception is thrown, the full exception text will be a huge help in finding the actual problem. Exceptions thrown in constructors can appear in the Exception.InnerException property. The sequence of calls that ended up in an exception being thrown will appear in the StackTrace property. Calling Exception.ToString() will return a string that contains all of that information for the current exception and any inner exceptions.
It means your compiler only has knowledge of the method that takes a type.
You could call
var incoming = serviceProvider.GetService(typeof(IService));
or you could add a
using Microsoft.Extensions.DependencyInjection;
to make sure your compiler knows the extension method that lets you specify your type as a generic parameter. This might need the package Microsoft.Extensions.DependencyInjection.Abstractions to be installed.
The short answer which is very well explained in the above posts:
ServiceProvider.GetService<T>();
with the use of following namespace which needs to be defined explicitly rather than relying on intellisense
using Microsoft.Extensions.DependencyInjection;
Also Keep a note there can be mutiple problems if you getting null exception after this:
In startup make sure Hostbuilder service is set to ServiceProvider value
ServiceProvider = host.Services;
Other could be the constructor of the T class couldn't resolve the dependency of the Interface being used.
**
Thanks ! Happy Coding :)
**
I'm trying to use autofac DI in my application. I created a wrapper class to abstract away all the autofac dlls:
FrameworkDependencyResolver : Logger, IFrameworkDependencyResolver
In this class I hold the container builder, and register all my dependencies in the application root. After registering my types I build it and hold the container:
Icontainer _container;
ContainerBuilder _builder
public FrameworkDependencyResolver()
{
_builder = new ContainerBuilder();
}
Deep in my application i want to use the FrameworkDependencyResolver object to resolve protocols and open connections to external applications, therefore I registered this object as IFrameworkDependencyResolver with the following code:
_builder.RegisterInstance(obj).As<T>();
Obj is thr FrameworkDependencyResolver, T is the interface
In my starter thread, I resolve object that takes the FrameworkDependencyResolver in his ctor, and it works perfectly, resolvings are fine, however when I resolve an inner layer(on new thread) that takes the FrameworkDependencyResolver in it's ctor and try to resolve a registered protocol object I face deadlock.
Exmaple:
main:
var rootResolver = new FrameworkDependencyResolver();
rootResolver.RegisterType<IClass3, Class3>(Lifecycles.Singleton);
rootResolver.RegisterType<IClass2, Class2>(Lifecycles.Singleton);
rootResolver.RegisterType<Container, TestContainer>(Lifecycles.Singleton);
rootResolver.RegisterObject<IFrameworkDependencyResolver, FrameworkDependencyResolver>(rootResolver);
rootResolver.BuildContainer();
rootResolver.Resolve<TestContainer>();
Console.ReadKey();
TestContainer code:
public TestContainer(IFrameworkDependencyResolver resolver) : base(resolver){}
protected override void InitializeContainer()
{
_class2 = DependencyResolver.Resolve<IClass2>();
Thread.Sleep(20000);
Console.WriteLine("Container initialize finished");
}
Class2 code:
public class2(IFrameworkDependencyResolver resolver)
{
_resolver = resolver;
var thread = new Thread(startMethod);
thread.Start();
Console.WriteLine("Class2 ctor ended");
}
void StartMethod()
{
_class3 = _resolver.Resolve<IClass3>();
Console.WriteLine("Start method finished");
}
The output of this simple example program is:
Class2 ctor ended
Container initialize ended
Start method finished
Meaning that the thread I created is waiting for the main thread to finish and only than it can resolve. I want to prevent this and make it possible to resolve anytime from every thread. Please help me understand what is causing this.
Thank you
Edit:
The problem is not solved because autofac resolves singletons from the root scope..I believe my problem is similar to the one described here : Autofac resolving a singleton creates a bottleneck
but I don't really understand the solution
Edit 2:
for the bottleneck issue I learned that ctors should not contain logic at all.
I also learned I probably shouldn't pass around my IFrameworkDependencyResolver object and should probably use Func<>.
My application structure:
I have a layer in my application that handles connection requests and for every kind of request creates a different kind of protocol (a different protocol object)
// For example lets say a protocol takes in ctor these 3 services + runtime configuration object:
public Protocol1(IFramingAgent, IFramingAlgorithm, IFramingParser, configObject configuration)
Each service is registered with key because each protocol uses a different one
And here is my terrible class:
public class ProtocolsLayer : Layer
{
private IFrameworkDependencyResolver _resolver;
private IConfigurationService _configService;
public ProtocolsLayer(IFrameworkDependencyResolver resolver, IConfigurationService configurationService)
{
_resolver = resolver;
_configService = configurationService;
}
void HandleConnection1()
{
// What I have at the moment (terrible):
// Resolve the fitting services (All keyed - key is received by the type, Resolve and ResolveWithParameters used here are my wrappers)
var agent = _resolver.Resolve<IFramingAgent>(typeof(Protocol1FramingAgent));
var algo = _resolver.Resolve<IFramingAlgorithm>(typeof(Protocol1FramingAlgorith));
var parser = _resolver.Resolve<IFramingParser>(typeof(Protocol1FramingParser));
// A parameter I get and pass to each protocol at runtime
var protocolConfig = _configService.GetConfig<Protocol1Configuration>();
// Finally resolve the protocol with it's parameters:
protocol = _resolver.ResolveWithParameters<IProtocol>(typeof(Protocol1), new List<object>{
agent, resolver, parser, protocolConfig
});
//...
// Theres gotta be a better way!!
}
void HandleConntection2()
{
// Same as in protocol1
}
void HandleConnection3()
{
// Same as in protocol1
}
}
Take in mind that I don't want references to autofac, meaning I can't use IIndex<> which I heard off.
Thanks!
I made a sample to reproduce your issue : https://dotnetfiddle.net/WOGwoD
If I summarize, your issue is that Autofac Resolve for only thread at a time.
Let take another code sample to reproduce the issue :
class Foo1
{
public Foo1()
{
Console.WriteLine("begin Foo1");
Thread.Sleep(1000);
Console.WriteLine("end Foo1");
}
}
class Foo2
{
public Foo2()
{
Console.WriteLine("begin Foo2");
Thread.Sleep(1000);
Console.WriteLine("end Foo2");
}
}
public class Program
{
public static void Main(string[] args)
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Foo1>().AsSelf().SingleInstance();
builder.RegisterType<Foo2>().AsSelf().SingleInstance();
IContainer container = builder.Build();
var t1 = Task.Run(() => container.Resolve<Foo1>());
var t2 = Task.Run(() => container.Resolve<Foo2>());
Task.WaitAll(t1, t2);
}
}
The output of this program is the following :
begin Foo1
end Foo1
begin Foo2
end Foo2
If you change the lifetime scope from SingleInstance to InstancePerDependency (the default one) for a single registration, the output will be :
begin Foo1
begin Foo2
end Foo1
end Foo2
We can see that Autofac lock the IContainer for Shared registration while it is activating a Shared registration.
The lock statement is Line 258 of LifetimeScope.cs.
I think this behavior is here to prevent issue with complex dependency graph. ie : What happens if Foo1 has a nested dependency on Foo2 ?
You won't be able to bypass this behavior of Autofac.
To change this behavior, you will need to change the way your code works. A constructor is not intended to take time. I recommend you to change your constructor to do only required things, if some of initialization process takes time I would defer it or refactor the code to ensure that constructor takes only few milliseconds to complete.
I created a wrapper class to abstract away all the autofac dlls
Your core code should not rely on dependency injection component. In your case, it looks like you use the IFrameworkDependencyResolver interface to lazy load component or to have a factory component. You should rely on Lazy<T> of Func<T> instead. See implicit relation type for more information.
I follow the same strategy in my application to wrap DI library with my classes to have ability to change it later on if I need to.
I followed the same approach, with only one difference
in your code you create ContainerBuilder in your class constructor and keep reference to it, this is the problem
instead, you may need remove away the ContainerBuilder instance, and just depend on Autofac.ILifetimeScope as constructor dependency for your FrameworkDependencyResolver, this dependency will be just injected by autofac runtime with correct lifetime scope.
then at any level on your code, you can just depend on FrameworkDependencyResolver as you need
EDIT
after i saw your update, i would recommend that you separate registration of your service from resolving instances, i.e make new class like FrameworkDependencyRegister and keep the other one for resolving and follow the steps answer above
in my opinion abstracting registration might be too much unneeded abstraction, you can just write one method to do this stuff using normal autofac APIs
im using unity container in my project and im trying to register the container to it self like this :
UnityContainer.RegisterInstance(UnityContainer);
But im getting the following exception :
Object synchronization method was called from an unsynchronized block of code.
I tried searching the exception but all I found was related to mutex.
The container already registers itself (as IUnityContainer), so you don't have to register it. Consider the following class:
public class MyClass
{
private readonly IUnityContainer m_UnityContainer;
public MyClass(IUnityContainer unity_container)
{
m_UnityContainer = unity_container;
}
}
Now if you simply resolve this class as follows, it will have the container injected into it.
var obj = container.Resolve<MyClass>();
Please note that having your classes depend on the container means that you want to use the container to locate services and this is considered an anti-pattern.