Get DI Context in derived class - c#

I am wondering how to get hold of my db context in a derived class (.net6 c#)
I have registered my context in Program.cs and on all of my controllers I can simply use this pattern to get the contect (same with services - they are all scoped services in program):
MyController(MyContext context)
{
}
This allows me to grab the context and work with it.
I have a class called person that is bought in from my db by EF power tools. I also have a class that derives from person like this:
public class ExtendedPerson : Person
{
public ExtendedPerson(Person psn)
{
Name = psn.Name;
Age = psn.age;
}
public bool MyBool()
{
//Here I need to get my context to do some DB checks
}
}
I tried to add the context to the constructor of ExtendedPerson in the same way as I would with the controller, but when creating an instance of ExtendedPerson I want it to get that context from DI instead of me having to new up a context.
The same could be said for services, all of my services are registered for DI, if I want to use them in this class surely I don't have to do this:
var extendedPerson = new ExtendedPerson(person, context, service1, service2);
Am I looking at this the wrong way somewhere??
Many thanks

Like mason already said, all the business logic that handles the Person entity, ideally belongs to the PersonService class with its own interface. In that service, all the dependencies can be resolved with constructor injection without a problem.
On the other hand, sometimes some simple calculated properties on EF entities come in handy. For those cases, you can create a partial class - that way, if you have autogenerated EF entity classes (DB first approach), scaffolding the DB won't overwrite your logic.

Related

C# Can we instantiate Interface with concrete type in ViewModel

I'm trying to implement MVVM pattern in WPF app. I've used dependency injection to get types inside my viewmodel's constructor like this.
private IEntity _newEntity;
private readonly IEntityService _entityService;
public MainViewModel(IEntity entity, IEntityService entityService)
{
_newEntity = entity;
_entityService = entityService;
}
Now can I do this for whatever reason _newEntity = new Entity(); or is it anti pattern? In other words can ViewModel be coupled with a concrete type?
It depends on what you want to archive.
If you want to call _newEntity = new Entity(); in MainViewModelss constructor like this
public MainViewModel(IEntityService entityService)
{
_newEntity = new Entity();
_entityService = entityService;
}
then you're creating a new object of class Entity right in the constructor and don't need to pass as an argument to the constructor via dependency injection anymore. But now each MainViewModel will have a different instance of Entity and probably more importantly you wont have a clean way to access the Entity from other ViewModels or Services. If this is what you want to happen, that's fine.
If you want other ViewModels or Services to use the same instance of Entity you would register an instance of Entity with your DI (dependency injection) container. Most DI-containers offer functionality for that use case, e.g. containerRegistry.RegisterSingleton<IEntity>(); in Prism.
With this out of the way...
If you don't see any future in which you're going to have a need to use classes apart from Entity which implement IEntity then (in my opinion) there is also no reason to make the code generic for no reason. This follows the YAGNI (You aren't gonna need it) principle, like don't implement abstractions you probably won't need. In this case you could register the Entity as the concrete type instead of the interface like this containerRegistry.RegisterSingleton<Entity>(); and change your MainViewModel to
private Entity _newEntity;
private readonly IEntityService _entityService;
public MainViewModel(Entity entity, IEntityService entityService)
{
_newEntity = entity;
_entityService = entityService;
}
There's also a nice video by SingletonSean where he doesn't us Interfaces but concrete classes for the constructor parameters of his ViewModels.
Please note that I just recently got into WPF, so I'm not claiming to be an expert at the time of writing this answer.
If the view model is responsible for creating entities, then creating these by doing new Entity() is perfectly fine.
The other option is to inject the view model with a factory that creates the entities on the behalf of the view model.

OWIN Self-Host Web API 2: How to Inject current user into generic Repository using Autofac

I'm building a OWIN Self-Hosted Web API 2 application and I'm using a generic repository pattern and using Autofac for dependency injection.
My generic repository class;
public abstract class Repository<T> : IRepository<T> where T : BaseEntity
{
private DbContext context_;
private Identity _currentUser; //This needs to be resolved
public Repository(DbContext context)
{
context_ = context;
}
public T Update(T item)
{
//item.ModifiedBy = _currentUser.UserName; // The value needs to be assigned
context_.SaveChanges();
return item;
}
}
Problem:
I need to access the current user and I need to update the database with ModifiedBy field.
I'm trying to avoid constructor injection, as the repository object is created in several places in project by passing DbContext as a constructor argument.
Is there any alternative ways to do this without modifying existing code much.
Could anyone help me to achieve my requirement.
Note:
Alternatively I can override the SaveChanges() method in DbContext class.
But again I cannot access the current there.
Identity is accessed from Thread.CurrentPrincipal.Identity, there is no problem setting this to whatever in a test setup eg. Thread.CurrentPrincipal = new ClaimsPrincipal(identity);
Edited
Yes CurrentPrincipal is safe to use, you would normally create some utilities functions to read out the values you need. Or you could of course create your own abstraction, and inject that to your classes, but I don't see the point of that.
btw. generic repositories are never a wise choice (read up on DDD).

How to set connection in Entity Framework 6 using Code-Based Configuration

I'm a bit confused by the (sparse) MSDN documentation on EF6 code-based configuration. I have a WPF application that needs to create an SQL connection based on command-line parameters and/or user input from a dialog. In older versions of EF I accomplished this by building the connection string and passing it to my derived DbContext every time.
It would be nice if I could avoid having to do that, since it also means having to pass the connection string to every view model that needs to use the context. It seems like the DbConfig in EF6 is on the path to accomplish that. Based on the docs, I have created a custom class that simply looks like this:
public class EfConfiguration: DbConfiguration
{
public EfConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
SetDefaultConnectionFactory(new SqlConnectionFactory());
SetDatabaseInitializer<DataContext>(null);
}
}
Which, from my understanding, EF will pickup and do something with. But my question is, how do I then set the connection string once the application is running? And in doing so, does that mean I can now instantiate my DbContext with no parameters?
In case anyone else runs across this problem, here's how I solved it:
DbContext has a constructor that accepts an existing connection. So my derived DbContext (called Entities in this case) has a constructor which looks like:
public Entities(IConnectionHelper connHelper)
:base(connHelper.GetConnection(), true)
{ }
The IConnectionHelper is an injected singleton that has properties for the server/db/uname/pw and upon changing them, builds an internal connection string using SqlConnectionStringBuilder. Since it's a singleton, the user can modify the properties from a dialog, for example, and they will still be accessible anywhere else. The GetConnection() method creates a connection from the factory:
SqlConnectionFactory connFactory = new SqlConnectionFactory(_connectionString);
return connFactory.CreateConnection(_connectionSettings.Database);
Where _connectionString is just the string I built and _connectionSettings is just a POCO that holds the various connection parameters.
Then to achieve the goal of having a parameterless construction of the DbContext, I made a simple factory which gets the IConnectionHelper constructor-injected as a dependency:
public EntitiesFactory(IConnectionHelper connHelper)
{
_connHelper = connHelper;
}
public Entities Create()
{
return new Entities(_connHelper);
}
I inject this factory into any classes that need it, and then it's a simple matter of:
using (var db = _entitiesFactory.Create())
{ ... }
You could also make the factory method static and not worry about injecting, but I did it this way to facilitate testing.
Just wanted to post here for my own future googling benefit that the DBContext base class also has a contructor that accepts a connection string, so you can go into your context text template and use that constructor :)
Easy Peasy

Object sharing and dynamic instance creation

I've a base class for business logic operations that is being inherited by my co-worker. This class expose a constructor which requires an objectContext as parameter. You can think of this base class as a component for atomic CRUD operations (all its select, insert, edit and delete method will always act on just one entity).
Then, I have a "super class" which its primary purpose is shared the objectContext between all the above base class in order to execute some business transaction and also it must provide any baseClass instance, if required.
So, I'm looking for to elegant way to "inject" superClass's objectContext into a baseclass:
public BaseClass<T> where T : entity
{
private ObjectContext _ctx;
public BaseClass(ObjectContext ctx){ _ctx = ctx;}
public virtual IList<T> Select(){..}
public cirtual voind Insert(T entity){..}
// other stuff
}
public class SuperClass
{
private ObjectContext _ctx = new...
public BaseClass<TEntity> LoadBaseClass(TBase, TEntity) where TBase : BaseClass<TEntity>, where TEntity : class
{
BaseClass<TEntity> obj = Activator.CreateInstance(typeof(TBase), _ctx); // share objectContext
}
public int SaveAll(){return _ctx.SaveChanges();}
}
As you can see, my super class is able to return some baseClass instance through its type and it's just what I want. However, if some inherited class defines its own contructor with other parameter my LoadBaseClass method will fails.
I would find a clean solution in order to avoid any kind of possibility of error during instance creations from LoadBaseClass method. The only way I know is to define a private contructor, but by this way no-one will be able to inherit baseclass anymore..
What you are looking for is called Dependency Injection. You are now trying to build this by hand but there are a lot of tools that already do what you want.
Dependency Injection is all about constructing objects and configuring how and when those objects are created. It comes down to splitting object creation from your business logic.
In your case, you are working with something called the Unit Of Work and Repository pattern. Using a Dependency Injection container like Ninject you can easily configure your UnitOfWork to be shared between all repositories like this:
var kernel = new StandardKernel();
kernel.Bind<IMyRepository>().To<ConcreteRepository();
kernel.Bind<IMyUnitOfWork>().To<ObjectContextImp>().InRequestScope();
IMyRepository repos = kernel.Get<IMyRepository>();
What Ninject (or any DI tool) will do is try to construct a IMyRepository. You've configured it to look for a ConcreteRepository. Then it notices that the ConcreteRepository takes a IMyUnitOfWork in its constructor. In this case you have mapped this to your ObjectContextIml and added the InRequestScope option.
InRequestScope is for ASP.NET web applications and it means that your context should be created once for each request. Ninject has a couple of different Object Scopes that you can use to configure how your object should be created and shared.
This way, you have complete control over how your objects are created.

DI: Associating entities with repository

I'm pretty new to the concept. What I'm trying to do is create a factory that will return an object that is used for repository functions. No problems there. So I create the instance of a concrete factory in main() and store it in a static property of App but my entities are in a separate dll. Does it make sense to pass the repository to each entity class in the constructor? This doesn't feel right. My question is: how is the best make my entities aware of which repository they should be using?
My App partial class looks like
public partial class App : Application
{
private static ICalDataAccess _daqFactory;
public static ICalDataAccess DataAccessFactory
{
set { _daqFactory = value; }
get { return _daqFactory; }
}
}
Maybe a little more code is in order.
public class Widget
{
public string Description { get; set; }
public int ID { get; set; }
private IWidgetRepository _widgetRepository;
public Widget(IWidgetRepository WidgetRepository)
{
_widgetRepository = WidgetRepository;
}
public void Save()
{
_widgetRepository.Save(this);
}
}
Am I doing anything egregious here?
I think the general recommendation is to keep your entities free from persistence concerns. That is, you have some code that retrieves the entities and uses them to perform whatever work needs to be done, resulting in new, deleted or modified entities, which the calling code then submits to the appropriate repository (or asks to be saved if you have something which tracks or detects modified entities, like EF or NHibernate).
That way your entities do not need to know about repositories at all.
I usually create a UnitOfWork helper class which exposes all of my repositories through a "public RepositoryFactory Repositories { get; }" property, so that simply by supplying an instance of the UnitOfWork class I have access to all of my data sources. UnitOfWork can then be injected via IoC to whatever class needs to have data access.
Some recommended reading on this topic:
Persistence Patterns
Discussion on this same topic elsewhere
Your description sounds more like the service locator pattern than dependency injection. Dependency injection typically looks like any object that needs some service object (such as data access) to do its work receives that service as parameter to its constructor.

Categories