How to use EF sharing same DbContext for multiple databases - c#

I am having a multitenant application which uses same web app with multiple Customer databases and having shared DbContext. When user logs in based on his credentials I provide connection string to DbContext and load the data. Problem occurs when multiple user logs in at the same time and they can see each others data as DbContext keeps on switching between different users.
I am using EF 5.0 and Autofac IOC mainly. Whats the best way to manage this?
How can I have my DbContext maintain its data for that specific user and will not change even though other users logged in and will have different database contexts for them?
Here's code in my Login page,
protected void LoginBtn_Click(object sender, EventArgs e)
{
int i = Convert.ToInt32(CustomerId.Text);
var builder = new ContainerBuilder();
var profile = _profileProvider.GetCustomerProfile(i);
ConnectionStringManager.ConnectionString = profile.connString;
builder.RegisterModule<CustomerDataModule>();
builder.Update(_container);
Response.Redirect("Home.aspx");
}
This is my static variable which gives connection string
public static class ConnectionStringManager
{
public static string ConnectionString { get; set; }
}
Here's my Module which has all entities and context classes,
public class CustomerDataModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(c =>
{
ConnectionString = ConnectionStringManager.ConnectionString;
return new CustomerDataContext(ConnectionString);
})
.As<ICustomerDataContext>()
.As<IDbContext>()
.InstancePerDependency();
builder.RegisterType<CustomerDataContextFactory>().As<ICustomerDataContextFactory>();
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces()
.InstancePerDependency();
}
}
Here's my DbContext,
public partial class CustomerDataContext: DbContext, ICustomerDataContext
{
public CustomerDataContext(string connectionString)
: base(connectionString)
{ }
.......
Here's my One of the repository,
public class CustomerRepository : GenericRepository<Customer, int>, ICustomerRepository
{
public CustomerRepository(ICustomerDataContext context)
: base(context, customer => customer.Id)
{
}
}

a static variable in a web app means sharing its data between all users at the same time. you need to move that value to a session variable, which is specific to each user.
var builder = new ContainerBuilder();
// will add `HTTP request lifetime scoped` registrations (InstancePerHttpRequest) for the HTTP abstraction classes
builder.RegisterModule(new AutofacWebTypesModule());
builder.Register<MyType>(ctx =>
{
var sessionBase = ctx.Resolve<HttpSessionStateBase>();
//now use the session value to retrieve the connection string
});

Related

EF Core execute against different databases with identical schema

EDIT: I also have a completely different approach where I have just about all of that crap commented out. I am able to call into my method and I configured the connect string to connect to the server, but not to the database. Then I want to connect to the different database depending on some data passed in (like the database name maybe?). Is there a way to call OnConfiguring on the fly so I can configure my connection string to be different each time I call my method?
I know some of you are going to look at this and roll your eyes with my stupidity, but we all had to start somewhere! I have a scenario with one database server but multiple databases all which share the same schema. Currently I am rewriting code for each database and it is a mess, so I am trying to clear it up. I have gotten myself pretty confused here so I am looking for advice from some of you gurus out there. I am a beginner here and trying to do something I find very advanced here so go easy on me. I will keep my examples with just two databases, but really there are 10+ databases that are all the same that I need to switch between often. My goal is to try to get rid of this 1, 2, 3, 4, 9, 10, etc stuff all over the place when I want to save or access a record, and have one thing controlling it all.
I created a base class for my database context
public partial class opkDataBaseContext : DbContext
{
private DbContextOptions<opkData1Context> options1;
private DbContextOptions<opkData2Context> options2;
public opkDataBaseContext()
{
}
public opkDataBaseContext(DbContextOptions<opkDataBaseContext> options)
: base(options)
{
}
public opkDataBaseContext(DbContextOptions<opkData1Context> options)
{
this.options1 = options;
}
public opkDataBaseContext(DbContextOptions<opkData2Context> options)
{
this.options2 = options;
}
public virtual DbSet<OrgUnits> OrgUnits { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
}
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
public void CreateNewOrganization(CreateCompleteOrgViewModel model)
{
var nameParameter = new SqlParameter("#TopLevelOrgName", model.Name);
var codeParameter = new SqlParameter("#Code", model.Code);
var DbNameParameter = new SqlParameter("#DBName", model.DbCatalog);
var debugParameter = new SqlParameter("#debug", "0");
var firstNameParameter = new SqlParameter("#FirstName", model.FirstName);
var lastNameParameter = new SqlParameter("#LastName", model.LastName);
var userNameParameter = new SqlParameter("#Username", model.UserName);
this.Database.ExecuteSqlRaw("CreateRootOrg #TopLevelOrgName, #Code, #DBName, #debug, #FirstName, #LastName, #Username",
nameParameter, codeParameter, DbNameParameter, debugParameter, firstNameParameter, lastNameParameter, userNameParameter);
}
Here is my Startup.cs
public void ConfigureServices(IServiceCollection services)
{
if (_env.IsProduction())
{
var opkCoreConnection = Configuration.GetConnectionString("opkCoreDatabase");
services.AddDbContext<opkCoreContext>(options => options.UseSqlServer(opkCoreConnection));
var opkData1Connection = Configuration.GetConnectionString("opkData1Database");
services.AddDbContext<opkData1Context>(options => options.UseSqlServer(opkData1Connection));
var opkData2Connection = Configuration.GetConnectionString("opkData2Database");
services.AddDbContext<opkData2Context>(options => options.UseSqlServer(opkData2Connection));
var opkDataLocalBaseConnection = Configuration.GetConnectionString("opkDataBaseDatabase");
services.AddDbContext<opkDataBaseContext>(options => options.UseSqlServer(opkDataLocalBaseConnection));
Then I have one of these for each database:
public partial class opkData1Context : opkDataBaseContext
{
public opkData1Context()
{
}
public opkData1Context(DbContextOptions<opkData1Context> options)
: base(options)
{
}
My current error is:
"Error while validating the service descriptor 'ServiceType: Models.DataModels.opkDataBaseContext Lifetime: Scoped ImplementationType: Models.DataModels.opkDataBaseContext': Unable to activate type 'Models.DataModels.opkDataBaseContext'. The following constructors are ambiguous:\r\nVoid .ctor(Microsoft.EntityFrameworkCore.DbContextOptions'1[Models.DataModels.opkDataBaseContext])\r\nVoid .ctor(Microsoft.EntityFrameworkCore.DbContextOptions'1[Models.opkData1Context])"} System.Exception {System.InvalidOperationException}
I have been messing with this all day. First, am I even going down the right path or is this just a dumb idea? Second, any idea where I am going wrong? Thank you!
I have a scenario with one database server but multiple databases all which share the same schema
This is very common, even a best-practice, in Software-as-a-Service (SaaS) applications.
While this is not obvious, it turns out to be quite simple. You just need some way to pick the connection string at runtime, probably based on a combination of the config and something in the HttpContext (like the user's identity, the path, the host header, etc). Then you configure the DbContext for DI like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddDbContext<MyDbContext>((sp, opt) =>
{
var httpContext = sp.GetRequiredService<IHttpContextAccessor>();
var config = sp.GetRequiredService<IConfiguration>();
string connectionString = GetConnectionStringFromHttpContext(httpContext, config);
opt.UseSqlServer(connectionString, o => o.UseRelationalNulls());
});
services.AddControllers();
}
where GetConnectionStringFromHttpContext is a custom method that builds the connection string based on the config and the HttpContext.
You could take a look a feature introduced in EF Core 5, which can change the connection or connection string on an already initialized context

Accessing dbContext in a C# console application

I have tried to figure this out, but I am stuck.
I have a Net Core 2 application with Service/Repo/Api/Angular layers - but now I want to 'bolt on' a console application and access all the goodies I have already built up. I seem to be in a mess of static objects and DI and null parameters. Anyway, here is a simplified version of my code.
namespace SimpleExample
{
class Program
{
private static ApplicationDbContext _appDbContext;
public Program(ApplicationDbContext appDbContext)
{
_appDbContext = appDbContext;
}
static void Main(string[] args)
{
var instance = new Program(); // this doesn't work!
var instance = new Program(_appDbContext); // neither does this!
instance.GetData();
}
private void GetData()
{
Console.WriteLine("Let's read some data! Press a key to continue.");
Console.ReadLine();
var data = "my data";
var result = GetId(data);
}
private string GetId(string original)
{
var data = _appDbContext.Data
.Where(x => x.Name == original.Trim)
.FirstOrDefault();
return data;
}
}
}
I am getting the classic
'An object reference is required for the non-static field'
error. Then from investigating on here I changed things to static and then everything becomes null.
It's not just the DbContext I am trying to inject. I'm also trying to inject
private ManagerService _managerService;
but getting same errors.
Update
If I try
private static ApplicationDbContext _appDbContext = new
ApplicationDbContext();
as suggested a few times below, then I get the error
There is no argument given that corresponds to the required formal
parameter 'options' of
'ApplicationDbContext.ApplicationDbContext(DbContextOptions)'
OK, I have figured this out, and I'll post my answer for anyone else struggling in this situation.
When you launch the console app, your normal startup.cs doesn't execute, so you have to put a lot of that code in your console app.
private static SiteService _siteService;
private static ApplicationDbContext _appDbContext;
public static void Main()
{
var services = new ServiceCollection();
services.AddTransient<ISiteInterface, SiteRepo>();
services.AddTransient<SiteService>();
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer("blah-blah"));
var serviceProvider = services.BuildServiceProvider();
_siteService = serviceProvider.GetService<SiteService>();
_appDbContext = serviceProvider.GetService<ApplicationDbContext>();
GetData();
}
and now your _appDbContext will be available throughout the rest of your console app.
Hope that helps!
Basically, if you do not plan extensive usage of DbContext nor use DI, there is no need for ServiceProvider. Just remember to make DbContext instance short living and use it for single unit-of-work, not longer.
Your context may look like this:
using Microsoft.EntityFrameworkCore;
namespace YourNamespace;
public class ApplicationContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(#"Your conn string");
}
public DbSet<YourType> YourEntity { get; set; }
}
You can pass conn string by ApplicationContext ctor as well. This is nicely explained here by Microsoft .
Then you can utilise your ApplicationContext like this:
// Unit-of-work closed in using statement
// Here you can query/update your DbContext
using (var dbContext = new ApplicationContext())
{
var queryResult = dbContext.YourEntity.Where(....);
}
You can prepare number of such units-of-work as separate methods for querying a database.
Your repository service can consist of these methods.
Then you can instantiate the service as needed.

DbContext is Disposed When Using Autofac Dependency Injection on WebApi project

I have a WebApi project using Entity Framework 6.0, Autfac for DI and CQRS architecture. The problem I have that DbContext isn't disposing how it supposed to. The action I take:
I run two quick requests, e.g. send request from Postman to one endpoint, runtime stops on breakpoint in controller method, I send second request to another endpoint in different controller.
Resume Runtime
if the second request finished before the first one is done, the first one throws and error that dbcontext was disposed and it cannot run whatever it was supposed to do
Originally problem appeared when I posted and patched from frontend one after another.
It seems like lifetime scope is not really per-request. It seems like all dbcontexts are disposed on one of the request's end. The other one does not have anything to work with.
How is it configured?
Starting from the highest layer - controller:
public class UsersController : BaseController, IUsersApi
{
private readonly IUserService _userService;
public UsersController(IUserService userService, ILogging logging) : base(logging)
{
_userService = userService;
}
[HttpGet]
[Route("api/users")]
public IList<UserDto> GetUsers()
{
try
{
return _userService.GetAllUsers();
}
catch (Exception e)
{
_logger.Error(e);
_logger.Trace(e);
throw;
}
}
[HttpPatch]
[Route("api/users/")]
public IHttpActionResult EditUsers(ICollection<UserEditDto> model)
{
try
{
_userService.EditUsers(model);
return Ok();
}
catch (Exception e)
{
_logger.Error(e);
_logger.Trace(e);
return BadRequest("Error");
}
}
}
Service layer:
public class UserService : IUserService
{
private readonly IServiceTools _serviceTools;
private readonly IUserQuerier _userQuerier;
public UserService(IServiceTools serviceTools, IUserQuerier userQuerier)
{
_serviceTools = serviceTools;
_userQuerier = userQuerier;
}
public void EditUsers(ICollection<UserEditDto> model)
{
var mapper = _serviceTools.AutoMapperConfiguration.Configure().CreateMapper();
var userEditCommands = mapper.Map<ICollection<UserEditDto>, ICollection<EditUserCommand>>(model);
foreach (var command in userSaveCommands)
{
_serviceTools.CommandBus.SendCommand(command);
CacheHelper.Clear(command.Id.ToString());
}
}
public IList<UserDto> GetAllUsers()
{
var allUsers = _userQuerier.GetAllUsers();
var result = allUsers.Select(x => new UserDto()
{
...
}).ToList();
return result;
}
}
Service Tools interface where command bus sits:
public interface IServiceTools
{
ICommandBus CommandBus { get; }
IAutoMapperConfiguration AutoMapperConfiguration { get; }
IIdentityProvider IdentityProvider { get; }
}
public class ServiceTools : IServiceTools
{
public ServiceTools(ICommandBus commandBus, IAutoMapperConfiguration autoMapperConfiguration, IIdentityProvider identityProvider)
{
CommandBus = commandBus;
AutoMapperConfiguration = autoMapperConfiguration;
IdentityProvider = identityProvider;
}
public ICommandBus CommandBus { get; }
public IAutoMapperConfiguration AutoMapperConfiguration { get; }
public IIdentityProvider IdentityProvider { get; }
}
And whatever handler for command:
public class EditUserHandler : IHandleCommand<EditUserCommand>
{
private readonly ICommandsContext _commandsContext;
public SaveUserHandler(ICommandsContext commandsContext)
{
_commandsContext = commandsContext;
}
public void Handle(EditUserCommand command)
{
... using dbcontext here...
}
}
}
For DI I use Autofac, all resources are set to per-request lifetime, split into modules, e.g. module for data access
public class DataModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AppNameDbContext>().As<ICommandsContext>().InstancePerRequest();
builder.RegisterType<AppNameDbContext>().As<IQueryContext>().InstancePerRequest();
base.Load(builder);
}
}
The difference between both interfaces is that IQueryContext cannot change entity states and use SaveChagnes() method. IQueryContext have all DbSets in it, while ICommandsContext inherits from it and adds SettingState methods (added, modified, deleted) and SaveChanges() method.
IQueryContext is injected into queries and ICommandsContext into commands as seend in example aboove.
Now the Autofac config for command bus looks like that:
public class InfrastractureModule : Module
{
private ICommandsContext _commandsContext;
private ITranslationsCommandsContext _translationsCommandsContext;
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AutoMapperConfiguration>().
As<IAutoMapperConfiguration>().InstancePerRequest();
builder.RegisterType<ServiceTools>().As<IServiceTools>().InstancePerRequest();
builder.Register(c =>
{
_commandsContext = c.Resolve<ICommandsContext>();
_translationsCommandsContext = c.Resolve<ITranslationsCommandsContext>();
return new CommandBus(CreateHandlersFactory);
})
.As<ICommandBus>().InstancePerRequest();
base.Load(builder);
}
private IHandleCommand CreateHandlersFactory(Type type)
{
if (type == typeof(XXXCommand))
{
return new XXXHandler(_commandsContext);
}
}
While the command bus looks like that
public class CommandBus : ICommandBus
{
private readonly Func<Type, IHandleCommand> _handlersFactory;
public CommandBus(Func<Type, IHandleCommand> handlersFactory)
{
_handlersFactory = handlersFactory;
}
public void SendCommand<T>(T command) where T : ICommand
{
var handler = (IHandleCommand<T>) _handlersFactory(typeof(T));
handler.Handle(command);
}
}
There is completely separate context used for translations for the app, but I do not thing that is important here.
I did not find any posts with similar problem. It only occurs when where two requests processed at the same time. I do not know if the configuration is wrong or Autofac messes things up, because it should not technically dispose dbcontext which was allocated for another request.
Sorry for the wall of text ;) I hope someone can help with that.
Obiously changing dbcontext's lifetime to SingleInstance fixed the problem, but we do not want that :)
SOLUTION EDIT:
As #ZeljkoVujaklija noticed CommandsDbContext declarations in InfrastractureModule seemed strange. I removed whole CommandBus registration from InfrastractureModule. Instead I created CommandsModule in the assembly where all the commands sit. It looks like that:
public class CommandsModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterAssemblyTypes(ThisAssembly)
.Where(x => x.IsAssignableTo<IHandleCommand>())
.AsImplementedInterfaces();
builder.Register<Func<Type, IHandleCommand>>(c =>
{
var ctx = c.Resolve<IComponentContext>();
return t =>
{
var handlerType = typeof(IHandleCommand<>).MakeGenericType(t);
return (IHandleCommand)ctx.Resolve(handlerType);
};
});
builder.RegisterType<CommandBus>()
.AsImplementedInterfaces();
}
}
Not only it fixes the problem but also gets rid of huge factory.
If you are running within ASP.NET Core you should run InstancePerLifetimeScope instead of InstancePerRequest
Use InstancePerLifetimeScope instead of InstancePerRequest. In previous ASP.NET integration you could register a dependency as InstancePerRequest which would ensure only one instance of the dependency would be created per HTTP request. This worked because Autofac was in charge of setting up the per-request lifetime scope. With the introduction of Microsoft.Extensions.DependencyInjection, the creation of per-request and other child lifetime scopes is now part of the conforming container provided by the framework, so all child lifetime scopes are treated equally - there’s no special “request level scope” anymore. Instead of registering your dependencies InstancePerRequest, use InstancePerLifetimeScope and you should get the same behavior. Note if you are creating your own lifetime scopes during web requests, you will get a new instance in these child scopes.
http://autofaccn.readthedocs.io/en/latest/integration/aspnetcore.html#differences-from-asp-net-classic

Using Autofac in integration tests with web api 2

I have been manually instantiating my services in my integration tests, but when I got to a serve that had Lazy dependencies, I did some research and found that you can actually use Autofac to resolve your services when doing your tests.
So, I wrote this class:
public class Container<TModule> where TModule: IModule, new()
{
private readonly IContainer _container;
protected Container()
{
var builder = new ContainerBuilder();
builder.RegisterModule(new TModule());
_container = builder.Build();
}
protected TEntity Resolve<TEntity>() => _container.Resolve<TEntity>();
protected void Dispose() => _container.Dispose();
}
And then in my context, I changed to this:
public class ProductContext : Container<AutofacModule>
{
public IProductProvider ProductProvider { get; }
public static ProductContext GiventServices() => new ProductContext();
protected ProductContext()
{
ProductProvider = Resolve<IProductProvider>();
}
public List<JObject> WhenListProducts(int categoryId) => ProductProvider.List(categoryId);
}
I have another context that seems to work (the tests pass) and that is using a MatchProvider. If I compare both in my Autofac module, they look like this:
builder.RegisterType<ProductProvider>().As<IProductProvider>().InstancePerRequest();
and
builder.RegisterType<MatchProvider>().As<IMatchProvider>().SingleInstance();
Because the MatchProvider is a singelton, it seems to have no issues being resolved, but the ProductProvider is an instance per request, this is where the issue seems to lie.
I get this error when running any tests that require that service:
No scope with a tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested.
I figured it was because I didn't have the right nuget packages installed. So I installed:
Autofac
Autofac.Integration.Owin
Autofac.Integration.WebApi
Autofac.Integration.WebApi.Owin
These are the same references that are used where my module is defined, but this did not help.
Does anyone know what I need to do to get this to work?
I couldn't find a suitable (easy) solution to this. I saw some people creating lifetime scopes themselves, which to me seemed like overkill and it wasn't "nice" code.
So, taking one of Autofac's principles: Any service that is registered multiple times; the last instance is the instance that is resolved.
So in my Container class, I just re-registered my InstancePerRequest services as InstancePerDependency instead. This solved my issue.
Here is my full code:
public class ContainerContext<TModule> where TModule: IModule, new()
{
private IContainer _container;
protected ContainerContext()
{
var builder = new ContainerBuilder();
builder.RegisterModule(new TModule());
// Because Autofac will resolve services using the last registration, we can change all our web api
// services to by InstancePerDependency instead of InstancePerRequest which is obviously better
// when testing.
builder.RegisterType<AnswerProvider>().As<IAnswerProvider>().InstancePerDependency();
builder.RegisterType<AttributeProvider>().As<IAttributeProvider>().InstancePerDependency();
builder.RegisterType<CategoryProvider>().As<ICategoryProvider>().InstancePerDependency();
builder.RegisterType<ClaimProvider>().As<IClaimProvider>().InstancePerDependency();
builder.RegisterType<ClientProvider>().As<IClientProvider>().InstancePerDependency();
builder.RegisterType<CriteriaProvider>().As<ICriteriaProvider>().InstancePerDependency();
builder.RegisterType<FeedProvider>().As<IFeedProvider>().InstancePerDependency();
builder.RegisterType<FormulaProvider>().As<IFormulaProvider>().InstancePerDependency();
builder.RegisterType<ImageProvider>().As<IImageProvider>().InstancePerDependency();
builder.RegisterType<GroupProvider>().As<IGroupProvider>().InstancePerDependency();
builder.RegisterType<QuestionProvider>().As<IQuestionProvider>().InstancePerDependency();
builder.RegisterType<StripeProvider>().As<IStripeProvider>().InstancePerDependency();
builder.RegisterType<ApiAiProvider>().As<IApiAiProvider>().InstancePerDependency();
builder.RegisterType<PiiikProvider>().As<IPiiikProvider>().InstancePerDependency();
builder.RegisterType<ProductProvider>().As<IProductProvider>().InstancePerDependency();
builder.RegisterType<SettingProvider>().As<ISettingProvider>().InstancePerDependency();
builder.RegisterType<TrackingProvider>().As<ITrackingProvider>().InstancePerDependency();
_container = builder.Build();
}
protected TEntity Resolve<TEntity>() => _container.Resolve<TEntity>();
protected void Dispose() => _container.Dispose();
}
And then, any context I use inherits this class:
public class ProductContext : ContainerContext<AutofacModule>
{
public IProductProvider ProductProvider { get; }
public static ProductContext GiventServices() => new ProductContext();
protected ProductContext()
{
ProductProvider = Resolve<IProductProvider>();
}
public List<JObject> WhenListProducts(int categoryId) => ProductProvider.List(categoryId);
}
Which means, when testing, I can just do this:
[TestFixture]
public class ProductProviderTests
{
[Test]
public void ShouldHaveProducts()
{
var services = ProductContext.GiventServices();
var products = services.WhenListProducts(1);
products.Count.Should().NotBe(0);
}
[Test]
public void ShouldHaveDuplicateVariants()
{
var services = ProductContext.GiventServices();
var products = services.WhenListProducts(1);
var anyDuplicate = products.GroupBy(x => x.SelectToken("variant").ToString()).Any(g => g.Count() > 1);
anyDuplicate.Should().Be(true);
}
[Test]
public void ShouldNotHaveDuplicateGtins()
{
var services = ProductContext.GiventServices();
var products = services.WhenListProducts(1);
var anyDuplicate = products.GroupBy(x => x.SelectToken("gtin").ToString()).Any(g => g.Count() > 1);
anyDuplicate.Should().Be(false);
}
}
This should help anyone else having the same issue.

autofac singleton initialization

I have a interface and class like this:
public sealed class UserService : IUserService
{
private readonly ILifetimeScope container;
public UserService()
{
this.container = this.ConfigureBuilder(new ContainerBuilder()).Build();
}
private ContainerBuilder ConfigureBuilder(ContainerBuilder builder)
{
builder.RegisterType<UserConfiguration>()
.AsImplementedInterfaces();
builder.Register(c => this.GetCredentialHelperAsync(c))
.As<ICredentialProvider>()
.SingleInstance();
return builder;
}
private async Task<CredentialProvider> GetCredentialHelperAsync(IComponentContext componentContext)
{
//This seems to causing problem as I think I cannot access component when I am build.
var config = componentContext.Resolve<UserConfiguration>();
if (config.User == null)
{
//ADD the user and set credentials
}
var userCredentials = new List<IUserCredential>();
return new UserCredentialProvider(userCredentials)
}
}
When I use autofac and I want to register this class as singleton, how do I do that. Problem is the value of user credentials is determined after reading credentials from file at run time.
With the above code I am getting exception building UserCredentialProvider as I think we cannot access objects during build. Is there a way out?

Categories