How can I pass runtime constructor parameter to resolve an object while using Microsoft Dependency Injection.
All that looks possible is to pass the parameter only in the startup while adding the object to the DI.
In Autofac, this is possible but nothing available for Microsoft DI:
var reader = scope.Resolve<ConfigReader>(
new NamedParameter("configSectionName", "sectionName"));
Related
I have a number of classes that consume API services and whose constructors follow the pattern below:
public class SomeClass
{
public SomeClass(IHttpClientFactory factory, ILogger<SomeClass> logger = null)
{
// ...
}
public SomeClass(HttpClient client, ILogger<SomeClass> logger = null)
{
// ...
}
}
The first constructor is the one used by .NET Core's built-in dependency injection (by calling IServicesCollection.AddHttpClient() from the Startup.ConfigureServices() method, and then calling IHttpClientFactory.CreateClient() in the constructor); the second constructor is mostly used for unit testing, to allow a HttpClient (or mock) to be passed in. This has worked fine until now, but this morning I started getting errors like the one below:
An unhandled exception has occurred
System.InvalidOperationException:
Unable to activate type
'Service'.
The following constructors are ambiguous:Void
.ctor(System.Net.Http.IHttpClientFactory,
Microsoft.Extensions.Logging.ILogger`1[Service])Void
.ctor(System.Net.Http.HttpClient,
Microsoft.Extensions.Logging.ILogger`1[Service])
at
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache
lifetime, Type serviceType, Type implementationType, CallSiteChain
callSiteChain)
... long stack trace elided...
This was working up till now. It seems strange that the dependency injection mechanism considers the constructors to be ambiguous when IHttpClientFactory and HttpClient do not share any common interfaces.
I updated both Visual Studio 19 to the latest version (16.8.2) and all NuGet packages in the solution at the weekend. The Microsoft.Extensions.DependencyInjection package is now version 5.0.0; previously it was version 3.1.9. I have worked around the issue for now by removing the constructors that take the HttpClient argument and replaced the code in my tests to use a mock IHttpClientFactory instead, so the actual impact was low. However, it would be help my peace of mind, if nothing else, to understand why this broke in the first place. Is there some aspect of configuring .NET Core dependency injection that I have overlooked? Or has the strategy to resolve dependencies changed subtly between versions 3.1.9 and 5.0.0?
Is there a way to create an IDbContext interface for DI (using AutoFac)?
i am using asp.net mvc 5 & EF 6.
and i would like to create an Interface for Dependency Injection.
There is some way to do it?
Currently i am register my Context class and it will work fine
builder.RegisterType<CustomContext>().SingleInstance().InstancePerLifeTimeScope();
DbContext's should be short-lived. A common pattern for working with EF Contexts is the Unit of Work pattern. There are a few out there for EF that can help manage the scope of a DbContext. At worst for ASP.Net you would want the DbContext lifetime set to the Request, no longer.
Option 1: (Recommended) Register a unit of work implementation (Such as Medhime's DbContextScope) and let that manage the DbContext scope. These follow the Interface/Concrete definitions to work well with DI.
Option 2: Register a DbContextFactory and use that to provide DbContexts. I.e.
using (var context = ContextFactory.Create())
{
// ....
}
Where ContextFactory is a defined DbContextFactory class implementing an IDbContextFactory interface.
Option 3: Register the DbContext itself as a PerRequest lifetime scope.
If your goal is to inject DbContexts to facilitate testing, I would highly recommend adopting a Repository pattern (Not a Generic Repository pattern I.e. Repository<TEntity>) and utilizing either Option 1 or Option 2. The advantage of a repository is that it serves as a boundary for the unit tests. Your "code under test" can then be served a Mocked repository class which in turn returns stubbed entities or IEnumerable<TEntity>/IQueryable<TEntity>. Mocking DbContexts and their DbSets is honestly a PITA. Repository methods can be tested if & as desired using integration-style tests talking to a real database.
I am using WCF web services and it was using OLD unity 2.0. So i updated Unity and other reference with latest version 5.0. I am getting exception:
Resolution failed with error: No public constructor is available for type xyz.Services.Contracts.Security.IAuthenticationService.
For more detailed information run Unity in debug mode: new UnityContainer().AddExtension(new Diagnostic())
Exception of type 'Unity.Exceptions.InvalidRegistrationException' was thrown.
Really i tried many things but not success. please any expert have a look.
I came across the same error upgrading from Unity version 3.5 to 5.11. In my case, during resolution the exception was the same ResolutionFailedException with message "No public constructor is available for IMyInterface" and having the same inner exception InvalidRegistrationException.
Well, the error messages and types of exceptions were misleading in my case; there was no registration problem nor did I ask for a public constructor for the interface. It seems that there has been a breaking change in the Resolve method overload which takes an instance name. Null names are no longer equivalent to empty string names. Replace your empty string name to null or use the other overload which doesn't specify an instance name:
var service = container.Resolve<xyz.Services.Contracts.Security.IAuthenticationService>();
OR
var service = container.Resolve<xyz.Services.Contracts.Security.IAuthenticationService>(null);
I am attempting to read the content of a file in Alfresco. I have seen examples that use
ContentService. Unforunately, when I try to use the example code, the ContentService
is not available.
I have added ContentService as a managed property of my managed bean in faces-config.xml
<managed-property>
<property-name>contentService</property-name>
<value>#{ContentService}</value>
</managed-property>
In my java code, I am using
ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
final ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
// contentService is an instance variable.
this.contentService = serviceRegistry.getContentService();
I am getting this Exception:
javax.faces.el.EvaluationException: Exception while invoking expression #{DeployAssetQADialog.start}
caused by:
javax.faces.el.PropertyNotFoundException: Bean: com.XXXXXXXXXX.CCCCCCCC.DeployAssetDialog, property: contentService
Can anyone tell me if there is something that I am missing? Thanks
PropertyNotFoundException sounds like your managed bean is missing a setter method.
How to expose spring managed beans to jsf may depend on the spring and/or jsf version you are using. Have a look at Spring beans injected into JSF Managed Beans for an example.
Finally, Make sure your Alfresco spring context is initialized before jsf kicks in.
Many issues in code
1) For each services which are injected you need to add getter setter method for them.
If you add getter setter for contentservice you can get rid of your error.
2) Other thing is you are trying to get conentservice though service registry in that case you need to inject service registry and add getter setter for that. Otherwise get contentservice instance directly as it is injected though faces-config and provided you have added getter setter for it you can directly use that instance of contentservice.
If I don't have the concrete class mapped to the interface, when Unity tries to resolve the type it gives me this error: "The current type, IFoo, is an interface and cannot be constructed. Are you missing a type mapping?".
However, for testing purposes, I'd like Unity to pass null to the interfaces that aren't mapped yet to concrete types.
Any suggestion to make this as the default behavior to "resolve" unmapped interfaces?
Thanks
I could let Unity pass null to my dependencies using the OptionalParameter while configuring the constructor injection.
container.RegisterType<IObject, MyObject>(
new InjectionConstructor(
new OptionalParameter<IFoo>()
)
);