I have configured a set of interface implementations with EntLib. unity block. The constructor of implementation classes work fine as soon as I run the application:
1. The interface to implement
when I run the application the cctor runs fine, which shows that unity resolution was successful:
But when I try to call a method of this class, the code just passes through without actually invoking the function of the implemented class:
Edit: Added on June 11, 2012
Following is the Unity Configuration I have. (This is all the unity configuration I am doing)
public class UnityControllerFactory : DefaultControllerFactory
{
private static readonly IUnityContainer container;
private static UnityControllerFactory factory = null;
static UnityControllerFactory()
{
container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container);
factory = new UnityControllerFactory();
}
public static UnityControllerFactory GetControllerFactory()
{
return factory;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return container.Resolve(controllerType) as IController;
}
}
I am unable to step into this code and the implementation simply skips out without executing anything. What is wrong here?
The actual problem was with a yield statement, which does not step into the code until the result is parsed.
When the debugger is stopped at the break point, right click on the line and select "step into specific", then choose the method you wish to step into.
Is this class/method in another assembly (not another project)? Its possible that the source for this class isn't loaded (or the debug symbols aren't refreshed correctly, restarting VS might fix it if that is the case.), so the debugger skips it. Also the method might be decorated with the DebuggerStepThroughAttribute, which causes the debugger to skip it.
Related
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 having trouble using DryIoc for constructor injection into a ViewModel using Prism with Xamarin. I am using the Nuget package Prism.DryIoc.Forms.
In my project I get the following error in AuthenticatePage.xaml.g.cs
Unable to resolve Object {RequiredServiceType=Project.ViewModels.AuthenticatePageViewModel} with 1 arg(s)
in wrapper Func<Xamarin.Forms.Page, Object> {RequiredServiceType=Project.ViewModels.AuthenticatePageViewModel} with 1 arg(s)
from container
with normal and dynamic registrations:
MainPage, {ID=44, ImplType=Project.Views.MainPage}}
NavigationPage, {ID=43, ImplType=Xamarin.Forms.NavigationPage}}
AuthenticatePage, {ID=45, ImplType=Project.Views.AuthenticatePage}}
Specifically, it points to the line
private void InitializeComponent() {
global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(AuthenticatePage));
}
Of note is that if I call the following in App.OnInitialized, the object resolves fine:
c.Register<INegotiator, Negotiator>(Reuse.Singleton);
var n = c.Resolve<INegotiator>();
n.ResumeSessionAsync(); // This works fine, no problems.
await NavigationService.NavigateAsync("NavigationPage/AuthenticatePage"); // Error thrown here
If I remove the constructor injection from my ViewModel it works fine (Aside from keeping the default navigationService injection, which works fine). Even trying to inject a basic class like ILogger (no dependencies) fails.
public AuthenticatePageViewModel(INavigationService navigationService, ILogger logger) : base (navigationService)
{
Title = "Authentication Page...";
}
I'm going to keep investigating, but is it obvious to someone here if I'm fundamentally doing something wrong? If I had to guess I would say it's to do with a conflict with Prisms built in Ioc container and DryIoc?
Edit:
I'm using the latest version of Prism.DryIoc.Forms available on NuGet (7.0.0.396) which says it includes DryIoc 2.12.26. I have so far simply followed the template available for Visual Studio which lists setting up navigation as follows:
protected override async void OnInitialized()
{
InitializeComponent();
var c = new Container();
c.Register<ILogger, LoggerConsole>(Reuse.Singleton);
c.RegisterMany(new[] { Assembly.Load("Project.UWP") },
serviceTypeCondition: type => type == typeof (ILocalFileHandler));
c.Register<INegotiator, Negotiator>(Reuse.Singleton);
// var n = c.Resolve<INegotiator>();
// n.ResumeSessionAsync(); // <- This will run fine. Negotiator class has ILogger and ILocalFileHandler injected into it.
await NavigationService.NavigateAsync("NavigationPage/AuthenticatePage");
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<MainPage>();
containerRegistry.RegisterForNavigation<AuthenticatePage>();
}
I can't find any info online on if/how I should be using Prism.DryIoc.DryIocContainerExtensions to set up navigation? Even modifying the sample app to include basic construction injection results in the error "Value Cannot Be Null" in the same xaml.g.cs file?
Prism 7.0 and below allows the exception to bubble up, in order to diagnose the root cause of your issue you want to better diagnose this issue I suggest you do a little try/catch to see what and where the error really is.
protected override void OnInitialized()
{
try
{
// Check if there is an initialization exception
var page = new AuthenticationPage();
// Validate that the page resolves ok
var page2 = Container.Resolve<object>("AuthenticationPage");
// Validate that your ILogger interface is registered and resolves ok
var logger = Container.Resolve<ILogger>();
// Check for Registration/initialization exceptions
var vm = Container.Resolve<AuthenticationPageViewModel>();
}
catch(Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
System.Diagnostics.Debugger.Break();
}
}
You haven't specified at what point you're getting this error, though typically with XAML Compilation enabled you would see exceptions in the {pageName}.xaml.g.cs during compilation and not runtime. Either way, given that your exception is coming from the generated XAML code behind class, this tells me it is most likely a problem with your XAML. A very simple way to validate this is to remove all of the XAML content in your AuthenticationPage so that you have an empty page.
Given the code you've provided as part of your question, I would say you have no registration for your ILogger interface which would likely throw an exception causing the problem you're seeing. Regardless of what/where the error is, the try/catch shown above would be the easiest way to determine the root cause.
Following #Dan S.'s diagnoses suggestion as well as reading this article (http://brianlagunas.com/whats-new-in-prism-for-xamarin-forms-7-0/) I realized that I should have been using the Prism.Ioc.ContainerRegistry abstraction layer to interface with DryIoc. Prior to this I had been working directly with DryIoc's classes.
Once I modified my registration code to use Prism.Ioc.IContainerRegistry it worked perfectly.
protected override void RegisterTypes(IContainerRegistry cr)
{
cr.Register<ILogger, LoggerConsole>();
cr.GetContainer().RegisterMany(new[] { Assembly.Load("Project.UWP") },
serviceTypeCondition: type => type == typeof(ILocalFileHandler));
cr.Register<INegotiator, Negotiator>();
cr.RegisterForNavigation<NavigationPage>();
cr.RegisterForNavigation<MainPage>();
cr.RegisterForNavigation<AuthenticatePage>();
}
I am trying to create tools for a game to learn, as well as improve my own playing experience.
The primary .NET assembly, csass.dll, that controls the client is heavily obfuscated, and I have no control over this .dll-file at all and reading it's code is very time consuming. The game also includes a mainapi.dll which handles the communication between server and client. I have full control over this assembly and I can listen to the servers responses and send my own requests, which already gives me some pretty nice functionality, however there are some limitations I'd like to work around.
csass.dll references mainapi.dll, by default mainapi does not reference csass. In csass.dll there is a class, let's call it clickHandler, that has a public, non-static method ClickObj() of return type void. I want to call this method from within mainapi.dll, but I have no idea how to go about this, given that I have to leave csass.dll untouched.
Are there any feasible ways to 'retrieve' a clickHandler object (to then call its ClickObj() method) from within the mainapi assembly, without making any changes in csass.dll? Appreciate any and all input!
Create an interface:
public interface IClickHandler
{
void ClickObject();
}
Now create a helper class implementing that interface:
using CsAss;
public class ObjectClicker : IClickHandler
{
CsAss _csass;
public ObjectClicker(CsAss csass)
{
_csass = csass;
}
public void ClickObject()
{
_csass.clickObject();
}
}
Add a dependency on an instance of the interface into your MainAPI class:
public class MainApi
{
IClickHandler _clickHandler;
public MainApi(IClickHandler clickHandler)
{
_clickHandler = clickHandler;
// Now you have a class that can call the click handler for you
}
}
Now wire it all up:
public void StartupMethod()
{
var csass = new CsAss();
IClickHandler clickHandler = new ObjectClicker(csass);
var main = new MainApi(clickHandler);
// TODO: Start your app now that MainApi is properly configured
}
That last step is the only potentially tricky part, depending on your project layout. You need something that can create an instance of CsAss, MainApi and ObjectClicker. Normally I would solve that with the dependency injection (DI) pattern, either using a framework such as Autofac or so-called "poor man's DI" by manually instantiating from a central startup method. That gets a little more difficult with Unity since there isn't an easily accessible startup point. You could start looking into https://github.com/svermeulen/Zenject and go from there for options.
Although I have seen Unity DI in apps before at a previous employer, I am adding it to one for the first time and am effectively a Unity Newbie. Consequently I am going slowly and testing as I go with Unity v4.0.1.
I have a console app with a simple dependency graph: LoadPayees, which has a dependency on PayeeLogic, which has a dependency on CommissionsRepository.
I have created a very simple Unity registration class with a single method:
public class UnityRegistration
{
public static void RegisterCommissionsTypes(IUnityContainer container)
{
container.RegisterType<ILoadPayees, LoadPayees>();
}
}
One resolution statement:
var processorInstance = (BaseTaskProcessor) container.Resolve(Type.GetType(classWithAssembly));
where class with assembly resolves to LoadPayees.
I have created a method injector in loadPayees for PayeeLogic:
[InjectionMethod]
public void Initialize(PayeeLogic payeeLogic)
{
this._payeeLogic = payeeLogic;
}
and a constructor injector in PayeeLogic for CommissionsRepository:
private CommissionsRepository _commissionsDal;
public PayeeLogic(CommissionsRepository commissionsDal)
{
this._commissionsDal = commissionsDal;
}
Having created this I then debugged in VS, expecting it to blow up with a null reference exception, since I hadn't explicitly registered PayeeLogic or CommissionsDAL with Unity, but it didn't. The entire process proceeded successfully as it did before I modified it to use Unity.
So either I have missed something stupid (which is likely) or Unity is able to automatically figure out all of LoadPayees' dependencies automatically, which is not what I expected.
So my question to Unity experts is, which of these is more likely?
The answer is yes, once the top level object is registered and resolved with Unity, it can figure out object dependencies, so object injection will work. However, so what. The main point of DI is being able to swap out concrete object instantiation for objects that implement the same interface, so if you want to do that, you need to register and resolve the entire object graph.
I made changes to my code as follows:
public static void RegisterCommissionsTypes(IUnityContainer container)
{
container.RegisterType<ILoadPayees, LoadPayees>();
container.RegisterType<IPayeeLogic, PayeeLogic>();
container.RegisterType<IPayeeDataAccess, CommissionsRepository>();
var payeeLogic = container.Resolve<PayeeLogic>();
var payeeDal = container.Resolve<CommissionsRepository>();
}
(LoadPayee resolution unchanged)
private IPayeeLogic _payeeLogic;
method injection:
[InjectionMethod]
public void Initialize(IPayeeLogic payeeLogic)
{
this._payeeLogic = payeeLogic;
}
constructor injection:
private IPayeeDataAccess _commissionsDal;
public PayeeLogic(IPayeeDataAccess commissionsDal)
{
this._commissionsDal = commissionsDal;
}
This was very much a newbie question, maybe even a stupid question? Hope it helps another Unity newbie to get their head around this product.
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