Managing DBContext state behind a data provider interface - c#

I have an interface IDataProvider which exposes (for sake of discussion) just 3 operations:
public interface IDataProvider
{
// get a list of projects (just metadata)
List<Project> ListProjects();
// load the Project by its GUID which we got from the metadata.
Project LoadProject(Guid id);
// save the project. underlying provider should determine to insert or update accordingly.
void SaveProject(Project data);
}
I am using DBContext accessing an SQL CE as the under lying data access layer data provider and I could implement:
public DataProvider : SqlCeDbContext, IDataProvider { ... }
or
public DataProvider : IDataProvider
{
List<Project> ListProjects()
{
using(var ctx = new SqlCeContext())
{
//... manage the life of the context for the API user.
}
}
// ...
}
or
public DataProvider : IDataProvider
{
SqlCeContext _mSqlCeContext = new SqlCeContext();
List<Project> ListProjects() { .. }
// ...
}
The three implementations will of course behave very differently with respect to connection and entity states. Since the interface "rules" does not enforce rules on this, which implementation is better? Or in case we should enforce one or the other, can it be done?

Assuming that this is on a mobile device (which I believe is the case due to the SqlCE references), I think that you may be making your life slightly more complicated than needed.
There is no reason that you can't open a connection at application startup and leave it open through the life of the application since there shouldn't be any other applications using the database.
We've had production WinCE apps for years that use this approach and have never had an issue with it.

Related

How to find out where my legacy application using NHibernate is leaking memory

I have a legacy application that I'm maintaining that is leaking memory.
I am reasonably confident that the source is the session management/dependency injection code. It uses Simple Injector and NHibernate.
To start, here are some helper classes and interfaces we use:
public class SessionFactory : Dictionary<string, Func<ISession>>,Helpers.ISessionFactory, IDisposable
{
public ISession CreateNew(string name)
{
return this[name]();
}
public void Dispose()
{
foreach (var key in Keys)
{
this[key]().Close();
this[key]().SessionFactory.Close();
}
}
}
public interface ISessionFactory
{
ISession CreateNew(string name);
}
Here is what the container initialization looks like:
private static void InitializeContainer(Container container)
{
var connectionStrings = System.Configuration.
ConfigurationManager.ConnectionStrings;
var sf1 = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db1"].ConnectionString
).BuildSessionFactory();
var sf2 = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db2"].ConnectionString
).BuildSessionFactory();
var sf3 = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db3"].ConnectionString
).BuildSessionFactory();
container.Register<ISessionFactory>(() =>
new SessionFactory
{
{"db1", sf1.OpenSession},
{"db2", sf2.OpenSession},
{"db3", sf3.OpenSession}
}, Lifestyle.Scoped);
}
Then, inside our base controller (other controllers inherit from it), this happens:
protected BaseController(ISessionFactory factory)
{
this.factory = factory;
db1Session = factory.CreateNew("db1");
db2Session = factory.CreateNew("db2");
db3Session = factory.CreateNew("db3");
}
From there, all of our methods can use a session from any database. Some request methods use multiple database sessions to complete their tasks. This project does not utilize the repository pattern at this point -- rewriting it would be an expensive operation. Is there any obvious memory leak I'm missing in this code?
I find your design very suspicious. First of all, your factory is leaking connections, since although you try to dispose it, the only thing you achieve is disposing things you just opened during disposal; this isn't very useful and means the already created connections will not be closed. Second, a design where your application requests the proper connection using a string based approach is error prone. Your application is probably dealing with multiple database schemas, where each connection relates to a certain schema. This means that connections aren't interchangeable and this warrants the use of a unique abstraction per schema. So instead of having one generic ISessionFactory abstraction that tries to serve all consumers (and currently fails), make things explicit by giving each unique schema its own abstraction. For instance:
public interface IDb1SessionProvider
{
ISession Session { get; }
}
public interface IDb2SessionProvider
{
ISession Session { get; }
}
public interface IDb3SessionProvider
{
ISession Session { get; }
}
By lack of context, I named the interfaces IDbXSessionProvider, but I bet you can come up with a better name.
This might look weird, since all interface have the same method signature, but remember that they have each a very different contract. The Liskov Substitution Principle describes that they should not share the same interface.
An implementation for such provider can be made as follows:
public class FuncDb1SessionProvider : IDb1SessionProvider
{
Func<ISession> provider;
public FuncDb1SessionProvider(Func<ISession> sessionProvider) {
this.sessionProvier = provider;
}
public ISession Session => provider();
}
And you can register such implementation in Simple Injector as follows:
var factory = new Configuration().Configure().SetProperty(
"connection.connection_string",
connectionStrings["db1"].ConnectionString)
.BuildSessionFactory();
var session1Producer = Lifestyle.Scoped.CreateProducer<ISession>(
factory.OpenSession, container);
container.RegisterSingleton<IDb1SessionProvider>(
new FuncDb1SessionProvider(session1Producer.GetInstance));
What this code does is creating a scoped InstanceProducer for the db1 session. The scoped InstanceProducer will ensure only one instance of that session is created during a certain scope (usually a web request) and it will ensure that the ISession implementation is disposed (if it implements IDisposable). The call to InstanceProducer.GetInstance() is wrapped in the FuncDb1SessionProvider. This session provider will call forward the creation of the session to the wrapped delegate.
With this design you can let your application code depend on the IDb1SessionProvider and that code can use it without the need to dispose it. Every call to IDb1SessionProvider.Session within the same session will ensure you get the same session and Simple Injector guarantees disposal on the end of the request.
It looks like you have invented your own interface called ISessionFactory. Given that you are using NHibernate which also provides an interface under this name, I would argue that it's VERY unfortunate to use the same names in your own code. You should pick a different name for your own interface and class to avoid confusion.
As for the question itself, NHibernate's ISessionFactory.OpenSession() does exactly that. It will open and return a session. There is no basis to assume that it will do something magic with regards to reuse or scoping.
To have NHibernate assist with contextual sessions, you need to configure the proper "context provider" and use, among other things, ISessionFactory.GetCurrentSession(). See Contextual Sessions in the NHibernate reference.
Alternatively, you can manage the sessions using whatever you like, but then you must use that mechanism to retrieve the current session and not expect NHibernate to know about it.

ASP.NET MVC Global DB

I'm trying to set the variable DB as global and use anywhere.
My problem is that I'm initialising twice the db. In the base controller and in atributes.
ie:
public class SettingsAttribute : ActionFilterAttribute {
public ApplicationDbContext db = new ApplicationDbContext();
public override void OnActionExecuting(ActionExecutingContext filterContext) {
...
}
and
[Settings]
public class BaseController : Controller {
public ApplicationDbContext db = new ApplicationDbContext();
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) {
...
}
I would like to create the var db just once, and access anywhere in the project.
How ca I do this?
Consider using of Dependency Injection pattern. For .NET there is for example Unity container, which implements a lightweight, extensible dependency injection container. Check the List of dependency injection containers for .NET, but it's quite old.
In general, Dependency injection is called Inversion of Control (IoC). That means, your classes, which are using for example your DB class, don't need to be dependent on a specific DB class. Instead, they just require a specific interface. DB class implementing this interface is injected from the outside and your class is decoupled from a specific implementation of DB class.
Some places to start with:
Dependency Injection on Wikipedia.org
Why does one use dependency injection?
An Absolute Beginner's Tutorial on Dependency Inversion Principle, Inversion of Control and Dependency Injection
Dependency Injection in Windows Communication Foundation
What about putting it in another class (an Helper, for instance), and access it like this:
private ApplicationDbContext db = null;
public ApplicationDbContext Db {
get {
if (db == null)
db = new ApplicationDbContext();
return db;
}
}
Best practice in this situation and (similar situations) is to implement a DI/IoC pattern , as #Dawid-Ferenczy mentioned in his answer. if you never worked with it before , it's a little abstract at the beginning but it's very useful in the long run , especially if your objects got complicated. You can search online for articles to learn more about the pattern itself.
#Dawid-Ferenczy mentioned the Unity container, but it's not limited to that , you can use any container you would like (Or even create your own if you need to ).
I personally use Ninject as it has a has a lot of support documentation and i found it easy to implement.
In your case (DB context) i would use Ninject and DI/IoC as follow:
1- Declare an interface for your DB Context DAL:
public interface IModelDBContext
{
//Your methods should go here
}
Your concrete class:
public class ModelDBContext : DbContext,IModelDBContext
{
//Your methods and other stuff here
}
Container part
(Ninject in my case , but you can use any other container)
public class NinjectDependencyResolver : IDependencyResolver
{
//Bunch of initialization and methods
Check out this : [Using ninject in MVC][2].
//Binding piece (Very important)
private void AddBindings()
{
//Context DB Binding
kernel.Bind<IModelDBContext>().To<ModelDBContext>();
//Other binding
}
}
Implementation part:
This is the fun and exciting part. anywhere in your application , if you need to implement your specific DB context you inject it with the constructor and it will be available for you to use:
In your case it will be something like this:
Public YourConcreteClass
{
Private IModelDBContext ModelDB; //Initiate an instance that you will use .
//DI by constructor
public YourConcreteClass(IModelDBContext mDB)
{
ModelDB=mDB;
}
//in the rest of your code you call ModelDB that has access to all of the methods and attributes you might need
}

How to version middle tier .NET application classes/methods

We have a typical N-Layer .NET application which sits in between our database and Web API service layer. This application consists of Business Layer, Data Repository/Access along with the related DTOs and Business Objects.
We have solutions in place to version our stored procedures and our Web API endpoints. The issue is the solution to version this middle layer, the actual class methods and schema objects. All Google searches come up with results for versioning source code in a source control solution or how to version using the Assembly info, neither of these are what we are referring to so results are limited.
So for example, we have two endpoints:
...api/v1/tax/charges
...api/v2/tax/charges
v1 must hit one version of the method CalculateTaxPctgs and v2 hits another version with updated business logic. Along with both needing to use different versions of the POCO Tax and TaxItems as we changed the name of one field in v2.
The easy to develop but hard to manage and very rigid/static solution would be to create two different methods, CalculateTaxPctgs_V1 and CalculateTaxPctgs_V2. This doesn't seem like a good idea.
Hard to find best practices or even alternative solutions for this dilemma. This is an enterprise application which takes millions of requests every day so performance is extremely important but so is code management and reliability.
Instead of different methods I'd use object inheritance. This way if a method stays the same between different versions you don't need to change the implementation in any way. You could then use a factory of some sort to create the instance required. For example:
public virtual class TaxCalculatorBase {
public virtual ICollection<TaxPercentage> CalculateTaxPercentages() {
DefaultImplementation();
}
}
public sealed class TaxCalculatorV1 : TaxCalculatorBase {
//Same implementation so no need to override
}
public sealed class TaxCalculatorV2 : TaxCalculatorBase {
//Same implementation but with a bit extra
public override ICollection<TaxPercentage> CalculateTaxPercentages() {
base.CalculateTaxPercentages();
ExtraStuff();
}
}
public sealed class TaxCalculatorV3 : TaxCalculatorBase {
//Different implementation
public override ICollection<TaxPercentage> CalculateTaxPercentages() {
NewImplementation();
}
}
public static class TaxCalculatorFactory {
public static TaxCalculatorBase Create(int version) {
switch (version) {
case 1: return new TaxCalculatorV1;
case 2: return new TaxCalculatorV2;
case 3: return new TaxCalculatorV3;
default: throw new InvalidOperationException();
}
}
}
public class CallingClass {
public void CallingMethod(int versionFromURL) {
var calculator = TaxCalculatorFactory.Create(versionFromURL);
var percentages = calculator.CalculateTaxPercentages();
percentages.DoStuffWithThem();
}
}
If the api implements an entire new version each time the factory can be more generic and something like:
public static class MyFactory {
public static TaxCalculatorBase CreateTaxCalculator(int version) {
switch (version) {
case 1: return new TaxCalculatorV1;
case 2: return new TaxCalculatorV2;
case 3: return new TaxCalculatorV3;
default: throw new InvalidOperationException();
}
}
}
//various other methods to create classes which depend on version
}
Obviously this depends on exactly how your solution is put together but would redirecting assembly versions be something you could leverage :
https://msdn.microsoft.com/en-us/library/7wd6ex19%28v=vs.110%29.aspx
You can redirect your app to use a different version of an assembly in a number of ways: through publisher policy, through an app configuration file; or through the machine configuration file.
To solve this problem we have implemented dynamically loading assemblies which handles over 80 different versions. It works well. We don't change the deployed software (unless there is a serious flaw) since it's part of a production system that we can't afford to break once it works.
We also have some critical changes over time, like using several different versions of .NET. To handle this we route requests to different application deployments.

DI with Repository and Services in different DLLs, keeping separation of concerns

I have a layered application with the following projects:
DAL (using EntityFramework with repositories)
DAL.Model (contains the entities, and is referenced by all the others)
Services
UI (in wpf)
The base repository looks like this:
public abstract class RepositoryBase<T> where T : class
{
private readonly MyContext context;
private readonly IDbSet<T> dbSet;
protected RepositoryBase(MyContext dataContext)
{
context = dataContext;
dbSet = context.Set<T>();
}
protected MyContext Context
{
get { return context; }
}
**And a series of virtual methods for Add, Delete, etc.
}
All repositories extend this one, such as:
public class MarketRepository : RepositoryBase<Market>
{
public MarketRepository(MyContext dataContext) : base(dataContext)
{
}
public IEnumerable<Market> GetAllMarkets()
{
return this.Context.Markets.ToList<Market>();
}
}
The services look like this:
public class MarketService
{
IMarketRepository _marketRepository;
public MarketService(IMarketRepository marketRepository)
{
_marketRepository = marketRepository;
}
public IEnumerable<Market> GetAllMarkets()
{
return _marketRepository.GetAllMarkets();
}
}
What I would like to achieve is that the UI layer would only have a reference to the Services layer, the Services layer only with the DAL layer (and all of them to Model, where the entities live) using DI (right now I'm using Unity).
The problem is, in my container in the UI I only want to do this
unity.RegisterType<IMarketService, MarketService>();
and not have to do it as well for the repositories, because then the UI layer would have a dependency on the DAL layer.
I thought about adding a parameterless constructor to the Service classes, like:
public MarketService() : this(new MarketRepository(*What would I put here?)) { }
but then I'm loosing the abstraction that the interface gives, and also I don't know what to do with the MyContext that the repository needs as a parameter; if I pass a new one, then I need to reference the DAL.
Should I change my repositories to create a new MyContext in the constructor, rather than getting it as a parameter?
How can I refactor my architecture to make it work properly and with minimal dependencies?
Well, I belive it is up to the bootstrapper to configure dependencies, in the higher level of the application. As it is usually the UI project, if it needs to reference other assemblies, so be it. If you do not like your UI project managing that, than create a bootstrapper project responsable for getting your app running and separete your UI classes in another one.
Your IoC container should support Dependency Injection using a string from an external configuration file. This way you are not hardcoding the mapping. Structuremap does this quite well, so I am sure other IoCs will.
Adding external dependenices as a parameter when creating an instance is the way to go.
I think you should make yourself more familiar with the different ways to configure Unity, so that the dependencies are resolved.
Could you elaborate why you are creating a repository when using a dependency injection framework?
When configuring DI, you should follow the same pattern - UI bootstrapper initializes Services, Services initialize DAL. (With autofac or ninject you could achiece this using modules. With unity you should emulate modules).
In pseudocode something like
//ui
void UILayer.ConfigureUnity(unity)
{
ServiceLayer.ConfigureUnity(unity)
}
//services
void ServiceLayer.ConfigureUnity(unity)
{
DAL.ConfigureUnity(unity)
unity.RegisterType<IMarketService, MarketService>();
}
//dal
void DAL.ConfigureUnity(unity)
{
unity.RegisterType<IMarketRepository, MarketRespository>();
unity.RegisterType<MyContext, MyContext>(); //not sure exact syntax - just register type for 'new Type()' activator.
}

Where to store application settings/state in a MVVM application

I'm experimenting with MVVM for the first time and really like the separation of responsibilities. Of course any design pattern only solves many problems - not all. So I'm trying to figure out where to store application state and where to store application wide commands.
Lets say my application connects to a specific URL. I have a ConnectionWindow and a ConnectionViewModel that support gathering this information from the user and invoking commands to connect to the address. The next time the application starts, I want to reconnect to this same address without prompting the user.
My solution so far is to create an ApplicationViewModel that provides a command to connect to a specific address and to save that address to some persistent storage (where it's actually saved is irrelevant for this question). Below is an abbreviated class model.
The application view model:
public class ApplicationViewModel : INotifyPropertyChanged
{
public Uri Address{ get; set; }
public void ConnectTo( Uri address )
{
// Connect to the address
// Save the addres in persistent storage for later re-use
Address = address;
}
...
}
The connection view model:
public class ConnectionViewModel : INotifyPropertyChanged
{
private ApplicationViewModel _appModel;
public ConnectionViewModel( ApplicationViewModel model )
{
_appModel = model;
}
public ICommand ConnectCmd
{
get
{
if( _connectCmd == null )
{
_connectCmd = new LambdaCommand(
p => _appModel.ConnectTo( Address ),
p => Address != null
);
}
return _connectCmd;
}
}
public Uri Address{ get; set; }
...
}
So the question is this: Is an ApplicationViewModel the right way to handle this? How else might you store application state?
EDIT: I'd like to know also how this affects testability. One of the primary reasons for using MVVM is the ability to test the models without a host application. Specifically I'm interested in insight on how centralized app settings affect testability and the ability to mock out the dependent models.
I generally get a bad feeling about code that has one view model directly communicating with another. I like the idea that the VVM part of the pattern should be basically pluggable and nothing inside that area of the code should depend of the existence of anything else within that section. The reasoning behind this is that without centralising the logic it can become difficult to define responsibility.
On the other hand, based on your actual code, it may just be that the ApplicationViewModel is badly named, it doesn't make a model accessible to a view, so this may simply be a poor choice of name.
Either way, the solution comes down to a break down of responsibility. The way I see it you have three things to achieve:
Allow the user to request to connect to an address
Use that address to connect to a server
Persist that address.
I'd suggest that you need three classes instead of your two.
public class ServiceProvider
{
public void Connect(Uri address)
{
//connect to the server
}
}
public class SettingsProvider
{
public void SaveAddress(Uri address)
{
//Persist address
}
public Uri LoadAddress()
{
//Get address from storage
}
}
public class ConnectionViewModel
{
private ServiceProvider serviceProvider;
public ConnectionViewModel(ServiceProvider provider)
{
this.serviceProvider = serviceProvider;
}
public void ExecuteConnectCommand()
{
serviceProvider.Connect(Address);
}
}
The next thing to decide is how the address gets to the SettingsProvider. You could pass it in from the ConnectionViewModel as you do currently, but I'm not keen on that because it increases the coupling of the view model and it isn't the responsibility of the ViewModel to know that it needs persisting. Another option is to make the call from the ServiceProvider, but it doesn't really feel to me like it should be the ServiceProvider's responsibility either. In fact it doesn't feel like anyone's responsibility other than the SettingsProvider. Which leads me to believe that the setting provider should listen out for changes to the connected address and persist them without intervention. In other words an event:
public class ServiceProvider
{
public event EventHandler<ConnectedEventArgs> Connected;
public void Connect(Uri address)
{
//connect to the server
if (Connected != null)
{
Connected(this, new ConnectedEventArgs(address));
}
}
}
public class SettingsProvider
{
public SettingsProvider(ServiceProvider serviceProvider)
{
serviceProvider.Connected += serviceProvider_Connected;
}
protected virtual void serviceProvider_Connected(object sender, ConnectedEventArgs e)
{
SaveAddress(e.Address);
}
public void SaveAddress(Uri address)
{
//Persist address
}
public Uri LoadAddress()
{
//Get address from storage
}
}
This introduces tight coupling between the ServiceProvider and the SettingsProvider, which you want to avoid if possible and I'd use an EventAggregator here, which I've discussed in an answer to this question
To address the issues of testability, you now have a very defined expectancy for what each method will do. The ConnectionViewModel will call connect, The ServiceProvider will connect and the SettingsProvider will persist. To test the ConnectionViewModel you probably want to convert the coupling to the ServiceProvider from a class to an interface:
public class ServiceProvider : IServiceProvider
{
...
}
public class ConnectionViewModel
{
private IServiceProvider serviceProvider;
public ConnectionViewModel(IServiceProvider provider)
{
this.serviceProvider = serviceProvider;
}
...
}
Then you can use a mocking framework to introduce a mocked IServiceProvider that you can check to ensure that the connect method was called with the expected parameters.
Testing the other two classes is more challenging since they will rely on having a real server and real persistent storage device. You can add more layers of indirection to delay this (for example a PersistenceProvider that the SettingsProvider uses) but eventually you leave the world of unit testing and enter integration testing. Generally when I code with the patterns above the models and view models can get good unit test coverage, but the providers require more complicated testing methodologies.
Of course, once you are using a EventAggregator to break coupling and IOC to facilitate testing it is probably worth looking into one of the dependency injection frameworks such as Microsoft's Prism, but even if you are too late along in development to re-architect a lot of the rules and patterns can be applied to existing code in a simpler way.
If you weren't using M-V-VM, the solution is simple: you put this data and functionality in your Application derived type. Application.Current then gives you access to it. The problem here, as you're aware, is that Application.Current causes problems when unit testing the ViewModel. That's what needs to be fixed. The first step is to decouple ourselves from a concrete Application instance. Do this by defining an interface and implementing it on your concrete Application type.
public interface IApplication
{
Uri Address{ get; set; }
void ConnectTo(Uri address);
}
public class App : Application, IApplication
{
// code removed for brevity
}
Now the next step is to eliminate the call to Application.Current within the ViewModel by using Inversion of Control or Service Locator.
public class ConnectionViewModel : INotifyPropertyChanged
{
public ConnectionViewModel(IApplication application)
{
//...
}
//...
}
All of the "global" functionality is now provided through a mockable service interface, IApplication. You're still left with how to construct the ViewModel with the correct service instance, but it sounds like you're already handling that? If you're looking for a solution there, Onyx (disclaimer, I'm the author) can provide a solution there. Your Application would subscribe to the View.Created event and add itself as a service and the framework would deal with the rest.
Yes, you are on the right track. When you have two controls in your system that need to communicate data, you want to do it in a way that is as decoupled as possible. There are several ways to do this.
In Prism 2, they have an area that is kind of like a "data bus". One control might produce data with a key that is added to the bus, and any control that wants that data can register a callback when that data changes.
Personally, I have implemented something I call "ApplicationState". It has the same purpose. It implements INotifyPropertyChanged, and anyone in the system can write to the specific properties or subscribe for change events. It is less generic than the Prism solution, but it works. This is pretty much what you created.
But now, you have the problem of how to pass around the application state. The old school way to do this is to make it a Singleton. I am not a big fan of this. Instead, I have an interface defined as:
public interface IApplicationStateConsumer
{
public void ConsumeApplicationState(ApplicationState appState);
}
Any visual component in the tree may implement this interface, and simply pass the Application state to the ViewModel.
Then, in the root window, when the Loaded event is fired, I traverse the visual tree and look for controls that want the app state (IApplicationStateConsumer). I hand them the appState, and my system is initialized. It is a poor-man's dependency injection.
On the other hand, Prism solves all of these problems. I kind of wish I could go back and re-architect using Prism... but it is a bit too late for me to be cost-effective.

Categories

Resources