UnitOfWork + Repository patterns and Entity Framework impersonation - asp.net

I have used UnitOfWork and Repository patterns in my application with EF.
Actually my design provides that the UnitOfWork would create the ObjectContext class and inject inside the Repository concrete class. For example:
UnitOfWork.cs (initialization)
public DefaultUnitOfWork() {
if (_context == null) {
_context = new MyDataContext(ConfigSingleton.GetInstance().ConnectionString);
}
}
UnitOfWork.cs (getting a repository instance)
public CustomerRepository Customers {
get {
if (_customers == null) {
_customers = new CustomerRepository(_context);
}
return _customers;
}
}
This way the Repository classes have an already defined ObjectContext class and they can use it's methods to retrieve and update data.
This works nice.
Now I need to execute my queries impersonating the Application Pool Identity so I have decided to wrap the code in the constructor of the UnitOfWork within the impersonation.
Unfortunately this does not work because the ObjectContext is then passed to the Repository constructor and used later when a client of the repository calls, for example, FindAll().
I have experienced that the real connection to the database is made right before doing the query by Entity Framework and not exactly when I am creating the ObjectContext itself.
How can I solve this problem?

You could use one or more ObjectContext Factories (to create ObjectContexts), using different creation criteria, such as Connection String, for example. Your UnitOfWork could leverage a factory to get its Context and so could the Repository, but I think you've missed the point of UnitOfWork if it is leveraging a different ObjectContext than your Repository.
A UnitOfWork should consist of one or more operations that should be completed together, which could easily leverage multiple repositories. If the repositories have their own ObjectContexts separate from the UnitOfWork, I don't see how committing the UnitOfWork will achieve it's purpose.
I think either I've misinterpreted your question completely or you've left out some pertinent details. Good Luck!

Related

Can Prism use .NET Core's built in Dependency Injection?

I'd like to start a WPF app using .NET Core 3.1
Can Prism make use of .Net Core's built-in DI (IServiceCollection) or do I have to use something like Unity?
If Prism cannot use the built-in DI, can they exist side-by-side?
Can Prism make use of .Net Core's built-in DI
From what I've seen you can't really replace Prism's DryIot with the ASP.NET Core build-in one. Mainly DryIot is more feature-full than the ServiceCollection API. There is this opensource package I've found that has an IContainerExtension implementation using ServiceCollection, but per the developer's own words this is more of a proof of concept rather than sable solution.
If Prism cannot use the built-in DI, can they exist side-by-side?
Yes, they can. With a caveat - you cannot simply register a service in ServiceCollection and expect to be able to inject that service directly in your App, Modules and ViewModels. This will fail because those files are managed by the Prism framework and thus injection will only work for services you have registered using the IContainerRegistry interface.
Benefits
Why would you do it? As the build-in IoT container the ServiceCollection API is well-known, thus it will be simpler for .Net developers. Furthermore you can structure you non-WPF projects to register services using the default container thus allowing them to be completely decoupled from your Desktop project. This is very good for more complex architectures like Domain-Driven Design.
Let's consider the following project structure:
solution
-- Desktop // Prism WPF application, containing only views and models
-- Application // Class library, containing operational logic.
Let's say that as a part of the Application project you need an IUserService which holds information about the current user that has to be populated in-memory when the user authenticates in the Desktop app. A registration method would look like this:
public IServiceCollection AddServices(this IServiceCollection services)
{
services.AddSingleton<IUserService, UserService>()
}
So now we need to inject it inside the Desktop project. I suggest two methods:
Simple
Seemless
Simple
This approach requires very simple startup configuration. The caveat is that you will not be able to inject your services directly in the constructor, but through the IServiceProvider interface.
Reference Microsoft.Extensions.DependencyInjection
Call your service registration method in App:
protected override void RegisterTypes(IContainerRegistry container)
{
// Build service provider using the ServiceCollection API
var provider = new ServiceCollection()
.AddServices()
.BuildServiceProvider();
// Register IServiceProvider within DryIot and provide
// a factory method to retrieve the service instance
container.Register<IServiceProvider>(() => provider);
}
Inject IServiceProvider where you need IUserService. For this example I'll use a Prism Module:
public class Module : IModule
{
private readonly IUserService userService;
public Module(IServiceProvider serviceProvider)
{
this.userService = serviceProvider.GetService<IUserService>();
}
...
private void Authenticate()
{
this.userService.IsAuthenticated = true;
}
}
That's it, you can now use your ServiceCollection registered dependency wherever you can access the IServiceProvider through Prism injection. This is the approach I recommend, because we are simply wrapping the .Net container in Prism's.
Seemless
This is where it gets a bit more interesting. Full disclaimer - you might encounter problems using this approach. I have not yet tested this beyond the most basic use-case. The only advantage this method offers is that you will be able to directly inject services in the constructor, instead of having to go through the IServiceProvider.
In its essence this method is simply looping through the ServiceCollection and registering all services directly in the Prism container. If we take a look at the implementation of ServiceCollection - it is simply a list of ServiceDescriptors. Upon further inspection we observe that ServiceDescriptior contains a bunch of constructors. We'll ignore those and focus on the properties:
ServiceType - the type that will be used when injecting
ImplementationType - type of the implementation to be injected
ImplementationInstance - instance of the implementation type
ImplementationFactory - factory delegate that returns an instance of the implementation type
LifeTime - Singleton, Scoped or Transient type
Let's now inspect the IContainerRegistry interface. We'll see that there are a lot of overloads of Register that accept Types, object and delegates.
Using that knowledge we can now create an adapter from ServiceDescriptor to registration of IContainerRegistry. The below implementation will only focus on Transient services, but the difference between service lifetimes is simply which registry method we call - Register for a Transient and RegisterSingleton for well Singletons.
Create and Adapter class with static method that accepts IContainerRegistry and ServiceDescriptor arguments:
public static void Register(IContainerRegistry container, ServiceDescriptor service)
{
// In case an implementation instance is provided we simply need to register it
if (service.ImplementationInstance != null)
{
containter.Register(service.ServiceType, service.ImplementationInstance);
}
// In case a factory is provided we have a bit more work.
// We need to modify it in order for it to be usable by the DryIot container
else if (service.ImlementationFactory != null)
{
var factory = service.ImplementationFactory;
var dryIotFactory = dryIotProvider =>
{
var provider = dryIotProvider.Resolve<IServiceProvider>();
return factory(provider);
};
container.Register(service.ServiceType, dryIotFactory);
}
// If no implementation or factory is provided then we simply register the
// types and let the container create the implementation instance on its own.
else
{
container.Register(service.ServiceType, service.ImplementationType);
}
}
The most tricky part here is the factory. To better understand factories in service-registration know that sometimes you may need access to other services to provide the correct implementation instance. For example if IHttpClient is registered you need to provide the IAuthorizationSerice with HttpAuthorizationService implementation instead of DesktopAuthorizationService.
Essentially we wrap the original factory method with a DryIot-compatible factory (accepts instance of DryIot container) that can supply the original factory with IServiceProvider instance.
Reference Microsoft.Extensions.DependencyInjection
Call your service registration method in App:
protected override void RegisterTypes(IContainerRegistry container)
{
var services = new ServiceCollection().AddServices()
foreach (var service in services)
{
Adapter.Register(container, service);
}
}
Inject IUserService directly in the module constructor:
public class Module : IModule
{
private readonly IUserService userService;
public Module(IUserService userService)
{
this.userService = userService;
}
}
Final thoughts
Again, I recommend the simple approach. Simplicity means lower learning curve and less room for errors. The inconvenience is minor in comparison.
Another fair warning - this is not production ready code. Especially the seemless method. I have yet to "battle-test" this implementation, but it might point you in the right direction.
If anyone has feedback/opinions I would be glad to read about it :)
Can Prism make use of .Net Core's built-in DI
Short Answer, NO
Here is a comment by #brianlagunas (The creator of Prism)
As I mentioned, we can't use IServiceProvider as we are in netstandard 1.0. The ServiceProvider and IServiceCollection is in netstandard 2.0. Also, there are a number of features that Prism needs that are to limited in the IServiceCollection implementation. Such as named instances and registrations, as well as a mutable container.
here is a comment by #dansiegel
I have spent a lot of time discussing this issue, and ultimately we cannot directly rely on IServiceProvider and IServiceCollection for a variety of reasons that extend beyond whether or not they are available.
here is the another comment also by
#brianlagunas
do I have to use something like Unity?
The ServiceCollection is "something like Unity". And, yes, you can use it with prism:
Create an IContainerExtension implementation that redirects to ServiceCollection
Derive from PrismApplicationBase and return your container extension from CreateContainerExtension

Optimize connection to SQLite DB using EF Core in UWP app

I'm currently working on a C# UWP application that runs on Windows 10 IoT Core OS on an ARM processor. For this application, I am using a SQLite DB for my persistence, with Entity Framework Core as my ORM.
I have created my own DBContext and call the Migrate function on startup which creates my DB. I can also successfully create a DBContext instance in my main logic which can successfully read/write data using the model. All good so far.
However, I've noticed that the performance of creating a DbContext for each interaction with the DB is painfully slow. Although I can guarantee that only my application is accessing the database (I'm running on custom hardware with a controlled software environment), I do have multiple threads in my application that need to access the database via the DbContext.
I need to find a way to optimize the connection to my SQLite DB in a way that is thread safe in my application. As I mentioned before, I don't have to worry about any external applications.
At first, I tried to create a SqliteConnection object externally and then pass it in to each DbContext that I create:
_connection = new SqliteConnection(#"Data Source=main.db");
... and then make that available to my DbContext and use in in the OnConfiguring override:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(_connection);
}
... and then use the DbContext in my application like this:
using (var db = new MyDbContext())
{
var data = new MyData { Timestamp = DateTime.UtcNow, Data = "123" };
db.MyData.Add(data);
db.SaveChanges();
}
// Example data read
MyDataListView.ItemsSource = db.MyData.ToList();
Taking the above approach, I noticed that the connection is closed down automatically when the DbContext is disposed, regardless of the fact that the connection was created externally. So this ends up throwing an exception the second time I create a DbContext with the connection.
Secondly, I tried to create a single DbContext once statically and share it across my entire application. So instead of creating the DbContext in a using statement as above, I tried the following:
// Where Context property returns a singleton instance of MyDbContext
var db = MyDbContextFactory.Context;
var data = new MyData { Timestamp = DateTime.UtcNow, Data = "123" };
db.MyData.Add(data);
db.SaveChanges();
This offers me the performance improvements I hoped for but I quickly realized that this is not thread safe and wider reading has confirmed that I shouldn't do this.
So does anyone have any advice on how to improve the performance when accessing SQLite DB in my case with EF Core and a multi-threaded UWP application? Many thanks in advance.
Secondly, I tried to create a single DbContext once statically and share it across my entire application. So instead of creating the DbContext in a using statement as above, I tried the following...This offers me the performance improvements I hoped for but I quickly realized that this is not thread safe and wider reading has confirmed that I shouldn't do this.
I don't know why we shouldn't do this. Maybe you can share something about what you read. But I think, you can make the DBContext object global and static and when you want to do CRUD, you can do it in main thread like this:
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
//App.BloggingDB is the static global DBContext defined in App class
var blog = new Blog { Url = NewBlogUrl.Text };
App.BloggingDB.Add(blog);
App.BloggingDB.SaveChanges();
});
But do dispose the DBContext at a proper time as it won't automatically get disposed.

Web API & Service Layer & EF6 - Without repository pattern [duplicate]

This question already has answers here:
Implementing Repository pattern and doing Tests
(2 answers)
Closed 8 years ago.
I'm creating a new web application based on ASP.NET Web API and EF6.
ProjectName
-ProjectName.Data (All entity framework stuff)
-ProjectName.Service (All business logic)
-ProjectName.Web (ASP.NET Web API All front end logic)
I've read tons of information the repository pattern & UoW , and the vast array of options on its advantages or disadvantages with EF. (StackOverflow has 10,081 results for "repository pattern").
We have no plans EVER
to change to a different database and with EF6 i've read you can do Unit testing without additional abstraction.
I'm tending toward NOT using repository or UoW and instead talking directly to DbContext from the service layer.
Can anyone provide examples that implement EF6 without a repository, with a service layer ?
Even better a sample project or github project using this in real life ?
Edit:
Similar Questions:
Implementing Repository pattern and doing Tests
Generic Repository With EF 4.1 what is the point
these are question on the same subject but none of them provide good code example of using EF in a architecture similar to the one i described:
How to manage DbContext lifetime without repository / UoW?
How to implement unit testing using ef6 new features ?
Your question is too broad. There are too many ways to achieve the same result. Here is my two cents -
Although you do not want to use Repository, you still want to inject Dependencies using IoC container such as Ninject, Autofac and StructureMap.
If so, you just need to inject YourDbContext to Service class.
For example,
public class CustomerService : ICustomerService
{
private readonly YourDbContext _context;
private readonly ICacheService _cacheService;
...
public StateService(
YourDbContext context,
ICacheService cacheService,
...)
{
_context = context;
_cacheService = cacheService;
...
}
}

How can I access a service outside of a controller with Symfony2?

I'm building a site that relies quite heavily on a third party API so I thought it would make sense to package up the API wrapper as a service, however I'm starting to find instances where it would be useful to have access to it outside of a controller such as in an entity repository.
Also related to that is it would be useful to be able to get access to config values outside of a controller (again such as in an entity repository).
Can anyone tell me if this is possible and if not is there a suggested approach to doing this kind of thing?
thanks for any help
The Symfony distribution relies heavily on dependency injection. This means that usually, dependencies are injected directly into your object via the constructor, the setters or via other means (like reflection over properties). Your API wrapper service is then a dependency for other objects of your application.
That being said, it would be rather difficult to inject this service in an entity repository's constructor because it already requires some other parameters and I think it would not be possible to inject them because of the way we request the repository for an entity.
What you could do is to create another service which will be responsible of doing the work you were about to do in the entity repository. This way, you will be able to inject the entity manager, which will be used to retrieve the entity repository, you custom service and also another service holding your configuration values (There are other ways to share configuration values).
In my use case, I use a Facebook helper service that wraps Facebook API calls. This service is then injected where I need it. My entity repository is only responsible of doing database calls so it receives only the arguments it needs and not the whole dependency. Thus, it will not receive the helper but rather only the arguments needed to do a request, for example, a Facebook user id. In my opinion, this is the way to do it since I think the entity repository should not have dependencies on such helper objects.
Here a small example using YAML as the configuration:
# app/config/config.yml
services:
yourapp.configuration_container:
class: Application/AcmeBundle/Common/ConfigurationContainer
# You could inject configurations here
yourapp.api_wrapper:
class: Application/AcmeBundle/Service/ApiWrapperService
# Inject other arguments if needed and update constructor in consequence
yourapp.data_access:
class: Application/AcmeBundle/Data/Access/DatabaseAccessService
arguments:
entityManager: "#doctrine.orm.entity_manager"
apiWrapperService: "#yourapp.api_wrapper"
configuration: "#yourapp.configuration_container"
# Application/AcmeBundle/Common/ConfigurationContainer.php
public ConfigurationContainer
{
public function __construct()
{
// Initialize your configuration values or inject them in the constructor
}
}
# Application/AcmeBundle/Service/ApiWrapperService.php
public ApiWrapperService
{
public function __construct()
{
// Do some stuff
}
}
# Application/AcmeBundle/Data/Access/DatabaseAccessService.php
public DatabaseAccessService
{
public function __construct(EntityManager $entityManager, ApiWrapperService $apiWrapperService, ConfigurationContainer $configuration)
{
...
}
}
The at sign (#) in the config.yml file means that Symfony should inject another service ,having the id defined after the at sign, and not a simple string. For the configuration values, as I said previously, there is other means to achieve the same goal like using parameters or a bundle extension. With a bundle extension, you could define the configuration values directly into the config.yml and your bundle would read them.
In conclusion, this should give you the general idea of injecting services. Here a small list of documentation on the subject. Alot of links use the XML service definition instead of the YAML definition but you should be able to understand them quite easily.
Symfony Official DI
Fabien Potencier's articles on DI
Richard Miller's articles on DI (Check in his blog for the other DI articles)
Take note that the configuration I'm giving is working for Beta1 of Symfony2. I didn't update yet to Beta2 so there could be some stuff not working as they are in the Beta2 version.
I hope this will help you defining a final solution to your problem. Don't hesitate to ask other questions if you want clarifications or anything else.
Regards,
Matt
I would wrap this kind of behavior in a Symfony service(like a manager).
i would not inject any parameters or logic into the entity repositories, as they should mainly be used to fetch data using object manager queries.
I would put the logic in the services and if the service , require a database access it will call the entity repository to fetch data.

How to use Membership provider with EF Code First?

I have models based on EF Code First and I want to use them with the default MembershipProvider, but I don't know how to write the model correctly, so it won't erase all my data on recreating the tables when there were changes made to the model.
Have a look at this project
http://codefirstmembership.codeplex.com/
It has entity classes for users and roles, as well as a roleprovider and membershipprovider implementation. If you include the users and roles in your datacontext class the tables will be created in your database.
Your question has two parts.
How to use asp.net membership API with EF code first?
How to preserve existing data when model changes?
as for How to preserve existing data when model changes, as far as with EF 4.0/ asp.net mvc 3, database migrations are not yet supported. You will have to move to asp.net mvc 4.0/ EF 4.3 where database migrations are supported or use similar alternatives , but its still beta release.
asp.net mvc 4.0 database migration in scott gu's blog
Now coming to the point on how to use asp.net membership provider with EF code first. There are couple of challenges :
We cannot/should not do an join with asp.net membership provider tables. Its not recommended, so my suggestion will be to create a "adapter class" for asp.net membership provider classes. For ex :
public class UserAdapter
{
// all user related attributes. Not stored in membership schema, but your schema
public string UserProxyName;
// some attributes stored in membership schema
[NotMapped]
public string Email {
get
{
Membership.GetUser(UserProxyName).Email;
}
}
// some attributes stored in membership schema and not in your schema
[NotMapped]
public string[] UserRoles
{
get
{
return Roles.GetRolesForUser(UserProxyName);
}
}
}
Now for updating information , you may write some functions in Model itself, however i would suggest create a UserRepository with repository design pattern to handle user CRUD operations.
Second challenge is how to create the database on first run. As seeding becomes an issue, if you want to seed user information then seperately running aspnet_regsql is not efficient as membership schema is expected before the seeding happens. I came across this nice article , with some fine tuning it worked for me :
asp.net membership and EF
Currently (EF 4.1 CTP) EF Code First doesn't have that option. It always drops a table if you made changes to model.
Update:
EF 4.1 RTM allows you to create a custom database initializer and specify creation of db objects and data seeding.
If you are using SQL Server, then check this :
http://www.paragm.com/ef-v4-1-code-first-and-asp-net-membership-service/
There is also my library which basically allows you to define how almost everything should be configured including: key type, where the your context object is, and where your user/role entities are located. Extendable using abstract base classes or interfaces. Also works quite well out of the box with repository pattern / unit of work / IoC Containers.
Source: https://github.com/holyprin/holyprin.web.security
NuGet: https://nuget.org/packages/Holyprin.Web.Security
In my DbContext.cs file I have a Seed function where I call the ApplicationServices.InstallServices() to install the ASP.NET Membership to my database. Now everytime my initializer drop the database it recreates ASP.NET Membership schema again.
public class PanelInitializer : DropCreateDatabaseAlways<PanelContext>
{
protected override void Seed(PanelContext context)
{
//Install ASP.NET Membership
ApplicationServices.InstallServices(SqlFeatures.Membership | SqlFeatures.RoleManager);
new List<Panel>
{
The ApplicationServices class
using System.Configuration;
using System.Data.SqlClient;
using System.Web.Management;
namespace Lansw.Panels.DataAccess.Contexts
{
public class ApplicationServices
{
readonly static string DefaultConnectionString = ConfigurationManager.AppSettings["DefaultConnectionString"];
readonly static string ConnectionString = ConfigurationManager.ConnectionStrings[DefaultConnectionString].ConnectionString;
readonly static SqlConnectionStringBuilder MyBuilder = new SqlConnectionStringBuilder(ConnectionString);
public static void InstallServices(SqlFeatures sqlFeatures)
{
SqlServices.Install(MyBuilder.InitialCatalog, sqlFeatures, ConnectionString);
}
public static void UninstallServices(SqlFeatures sqlFeatures)
{
SqlServices.Uninstall(MyBuilder.InitialCatalog, sqlFeatures, ConnectionString);
}
}
}
Thanks to #ImarSpaanjaars http://imar.spaanjaars.com/563/using-entity-framework-code-first-and-aspnet-membership-together.

Resources