Previously i had to implement IDesignTimeDbContextFactory to get migrations running, e.g:
PM > Add-Migration Initial
PM > Update-Database
If not, the console threw an error and led me here: https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext#use-idesigntimedbcontextfactory.
So i did what it suggested and got migrations running.
After that i have created new projects, and i didn't have to implement the IDesignTimeDbContextFactory. Migrations worked anyway. How is this possible?
Same .NET Core version (2.0) on all of the projects.
Do we always need to create a IDesignTimeDbContextFactory, or is it just in certain situations?
Thanks!
Okay, here it goes:
If you have a default constructor in your DbContext or are using the Program.BuildWebHost() pattern established in the ASP.NET Core 2.0 project templates, you typically won't need an IDesignTimeDbContextFactory implementation.
In 2.0.0-preview1 Program.BuildWebHost() wasn't used and you needed a design-time factory.
See this thread for full discussion:
https://github.com/aspnet/EntityFrameworkCore/issues/9033
As Dan Banan stated, if a DbContext has a default constructor, it won't need an IDesignTimeDbContextFactory at design time. However, if it needs to be configured from Startup, it will need a constructor which takes accepts DbContextOptions<T> and invokes the corresponding base constructor. However, this will create another issue. The DbContext's OnConfigure method will be called regardless of which constructor is used.
To account for these details, I've found the following pattern to be useful:
DbContext Configuration and Dependency Injection
serviceCollection
.AddDbContext<MyDbContext>(
options => options.UseSqlServer(configuration.GetConnectionString("MyDb"),
ServiceLifetime.Transient
);
MyDbContext.cs
public class MyDbContext : DbContext
{
public SureshotDbContext()
{
// This allows for instantiation at design time.
}
public MyDbContext(DbContextOptions<MyDbContext> options) :
base(options)
{
// This allows for configuration in real applications.
}
protected override void OnConfiguring(
DbContextOptionsBuilder optionsBuilder
)
{
if (optionsBuilder.IsConfigured)
{
return;
}
optionsBuilder.UseSqlServer(nameof(TDbContext));
}
}
Related
I have a program in c#, dotnet 5.0, running on Linux Ubuntu, that registers a Singleton dependency:
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
services.AddGrpcReflection();
services.AddSingleton(Configuration);
services.AddSingleton<IExchangeService, HuobiAPI>();
services.AddSingleton<IMarketWriter, MarketCSVWriter>();
}
where HuobiAPI is
public class HuobiAPI : ExchangeServices
And HuobiAPI accepts gRPC calls. One of the gRPC methods defined in ExchangeService is SubscribeMarket2UDP:
public override Task<SuccessReply> SubscribeMarket2UDP(
MarketSubscriptionMessage request,
ServerCallContext context)
Now, whenever this method is called (from a remote program), a new instance of ExchangeService is created. However, my understanding is that this should be a singleton.
Is there any obvious reason for a AddSingleton dependency to create multiple instances of the same class?
I finally found a solution to the problem in "Dependency Injection: Principles, Practices, and Patterns - Steven van Deursen & Mark Seemann". Changing the registration of the dependency solved the problem. For some reason that I don't yet fully understand doing:
services.AddSingleton<IExchangeService, HuobiAPI>();
is bad and I guess it is called a 'Torn Lifestyle'.
Now doing:
services.AddSingleton<HuobiAPI>();
services.AddSingleton<IExchangeService>(c => c.GetRequiredService<HuobiAPI>());
Works fine and only one instance of the HuobiAPI class is created.
If anybody has any comments or explanation for this, feel free to comment. I'll have to dig more into the book to understand what is really going on here.
Scenario
I am trying to change my existing HttpClient to IHttpClientFactory. When I verified the existing code, its using using{...} statement which causes issues and it is mentioned here. So I thought of implementing singleton Http client and reached another blog related to this and it is here.
From all these, I understood that the best one is IHttpClientFactory introduced in .NET Core.
Implementation Plan
As this application is in ASP.NET MVC 4 and does not use DI, I have to do something to use without the DI framework. Based on my search, got answers from StackOverflow and planned to implement the same way. Meanwhile, I also got another project, which already removed all the dependencies and is ready to use in earlier projects without doing all things. The repo is HttpClientFactoryLite.
Question
Now I can use HttpClientFactoryLite by initializing this class? The description also mentioned it can be used along with the existing DI framework so that ClientFactory can be registered as a singleton. Please find the wordings from the readme
using HttpClientFactoryLite;
var httpClientFactory = new HttpClientFactory(); //bliss
If you are using dependency injection, make sure that IHttpClientFactory is registered as a singleton.
In my scenario, I don't have any DI framework added. So I am going to initialize the factory wherever I needed. Here I am confused that in 2 things
Is it necessary to make a singleton class for HttpClientFactoryLite?
How is this HttpClientFactory class disposed? Is there a need to dispose of it as part of the controller or same using statement etc?
Based on the answer from this, Microsoft.Extensions.Http provides the HttpClientFactory only, not the new optimized HttpClient. This is only available in .NET Core 2.1. So any difference in implementing IHttpClientFactory?
Please advise
ASP.NET 3.1:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSingleton<IHttpClientFactory, HttpClientFactory>();
}
ASP.NET will automatically pass the correct singleton to controllers which demand an IHttpClientFactory in their constructor.
Poormans variation without DI-Container:
public static class Singleton<TInterface>
{
private static TInterface instance;
public static TInterface Instance
{
get => instance;
private set => instance ??= value;
}
public static void Add<TConcrete>() where TConcrete : TInterface, new()
=> Instance = new TConcrete();
public static void Add<TConcrete>(TConcrete instance) where TConcrete : TInterface
=> Instance = instance;
// put dispose logic if necessary
}
Usage:
// Application Entrypoint
Singleton<IHttpClientFactory>.Add<HttpClientFactory>();
// Class/Controller Property
private readonly IHttpClientFactory httpClientFactory
= Singleton<IHttpClientFactory>.Instance;
I am getting the following error on the first db access after the application starts - "Unable to cast object of type 'System.Data.ProviderBase.DbConnectionClosedConnecting' to type 'System.Data.SqlClient.SqlInternalConnectionTds"
The error only thrown once, at the first method tries to read data from the database, after the application starts.
Re-calling the same method for the 2nd time and further, everything works fine.
Using .net core 1.1 with Entity Framework
I recently had this same exception in an ASP.NET Core 2 app with EF Core. In my case, the root cause was a problem with the scopes my dependency-injected DbContext. I had a controller and a service both using an injected DbContext. The service was a singleton, like this:
public class TestService{
public TestService(FooDbContext db)
{
this.db = db;
}
}
public class FooController{
public FooController(FooDbContext db, TestService testService)
{
this.testService = testService;
this.db = db;
}
}
public class Startup{
public void ConfigureServices(IServiceCollection services){
//...
services.AddDbContext<FooDbContext>(options =>
options
.UseSqlServer(Configuration.GetConnectionString("FooDbContext"))
);
services.AddSingleton<TestService>();
}
}
So the controller would use it's instance, and then if the singleton service also tried to use it's own instance, then it would give the error above about 90% of the time. I'm a little fuzzy on why this would be an issue, or be intermittent, but it became pretty clear in debugging that EF was reusing some underlying resources. I didn't dig into EF code debugging, but I suspect the controller instance was closed, and the service instance reused the connection, expecting it to be open. In reading, others suggested MultipleActiveResultSet=true in the connection string would fix, but this did not resolve the issue in my case. In my case, the fix was to change the service to Transient in Startup.cs, which was acceptable in this case, and possibly better:
services.AddTransient<TestService>();
I am using ASP.net core. I have problem with implementing dbcontext into singleton.
I need my singleton IModuleRepository to be running right after start of the project. So I am creating new instance of this dependency in public void ConfigureServices(IServiceCollection services) in Startup.cs file.
This singleton is using another singleton, so I am using it like this:
services.AddDbContext<ModulesDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).EnableSensitiveDataLogging());
...
services.AddSingleton<IModuleRepository, ModuleRepository>();
services.AddSingleton<ICommunicationRepository>(new CommunicationRepository(services.BuildServiceProvider().GetService<IModuleRepository>()));
In ModuleRepository I am using DBcontext.
// Db context
private readonly ModulesDbContext _modulesDbContext;
public ModuleRepository(ModulesDbContext modulesDbContext)
{
_modulesDbContext = modulesDbContext;
}
When I am calling _modulesDbContext.SomeModel.ToList(); I get error:
System.InvalidOperationException: An attempt was made to use the context while it is being configured. A DbContext instance cannot be used inside OnConfiguring since it is still being configured at this point.
How to avoid this error when I need this singleton to run after the project is started?
Thank you for your help.
As #Ilya Chumakov commented, you could just tell the DI container to use your concrete class like so:
services.AddSingleton<ICommunicationRepository, CommunicationRepository>();
Then any class can depend on ICommunicationRepository and get the concrete repository, which gets the Db context.
I figured out this problem. This calling of the dependencies were right. The error is that in CommunicationRepository I've created 2 Task and both of them were using the same DbContext - so it was using it multiple times. I had to say task.Wait();
Full code in constructor of the CommunicationRepository after correction:
// Add pernament communication
var task = new Task(AddPernamentCommunicationAll);
task.Start();
task.Wait();
// Add modules
var taskModules = new Task(AddModulesToList);
taskModules.Start();
Thank you for your answers.
I have a IUserService (and other services) that I am registering in bulk in my ServiceInstaller.cs:
container.Register(
AllTypes.FromAssemblyContaining<UserService>()
.Where(type => type.Name.EndsWith("Service"))
.WithService.DefaultInterface()
.Configure(c => c.LifeStyle.Singleton)
);
I then I have IAuthenticationService which I register as in my generic WindsorInstaller.cs file:
container.Register(Component.For(typeof (IAuthenticationService))
.ImplementedBy(typeof(AuthenticationService)));
Now things were working just fine until I added a public property for IAuthenticationService in my UserService.
It seems there is a circular dependacy or some timing issue of when things get registered, as I am getting the error:
Can't create component 'ABCD.Services.UserService' as it has dependencies to be satisfied.
ABCD.Services.UserService is waiting for the following dependencies:
Services:
- ABCD.Services.Interfaces.IAuthenticationService which was registered but is also waiting for dependencies.
ABCD.Services.AuthenticationService is waiting for the following dependencies:
Services:
- ABCD.Services.Interfaces.IUserService which was registered but is also waiting for dependencies.
How can I solve this issue?
You need to either:
Get rid of your circular dependencies (this is the preferred option), or
Work around them, by using property injection, rather than constructor injection.
Using property injection (as illustrated in Steven's answer) allows you to create instances of your classes without providing all the dependencies at the time of creation. The downside is that it is not as obvious to users of the class what they need to do to instantiate and fully configure the instance.
For a nice explanation of how to refactor to remove a ciruclar dependency see this blog post by Miško Hevery:
Circular Dependency in constructors and Dependency Injection
Property injection will solve your problem, because it breaks the dependency cycle. Just look at Krzysztof's example and try to instantiate a UserService; You can't. Now take a look at the following example:
public class UserService
{
UserService(AuthenticationService a) { }
}
public class AuthenticationService
{
AuthenticationService() { }
public UserService UserService { get; set; }
}
In this example, the UserService dependency of the AuthenticationService is 'promoted' from a constructor argument to a property. Now you can create a user service like this:
var a = new AuthenticationService();
var s = new UserService(a);
a.UserService = s;
Breaking the circular dependency can be done with property injection and any dependency injection framework can be configured to allow property injection.
here's your scenario as I understand it:
public class UserService
{
UserService(AuthenticationService a){}
}
public class AuthenticationService
{
AuthenticationService (UserService a){}
}
How would you create instances of both classes, creating at most single instance of each class?