5
\$\begingroup\$

I’m currently aiming to make my first app for the Universal Windows Platform (UWP) / windows 10. It’s a small app but should follow some best practices patterns (although I’m considering it as a first step on new grounds, as I am more used to MVC/ASP.net programming and a bit WPF some time ago). I’m using following frameworks:

  • Prism (MVVM)
  • Unity
  • SQLite.Net-PCL (+Extensions)

I’m currently thinking about the best way to structure my app and how to organize data access. From my MVC times, I’m used to patterns like (Business)Services, Repositories and the Unit of Work (so that all repositories share the same DB connection) as sophisticated ways to encapsulated data access. However, as the lifetime of a DB connection was limited to a HttpRequest in the Web-Context, it does not seem reasonable to me to keep a DB connection alive for the lifetime of the whole App or maybe even for the lifetime of a ViewModel. Currently, I have several repositories for my entities, which inherit from a generic repository. These offer common methods like

  • public T Insert(T model)
  • T Update(T model)
  • etc.

My Unit Of Work looks like this:

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private readonly SQLiteConnection _context;
    private bool _isDisposed = false;

    private IEvaluationRepository _evaluationRepository;
    public IEvaluationRepository EvaluationRepository
    {
        get { return _evaluationRepository; }

    }

    public UnitOfWork(SQLiteConnection context, ITraceListener traceListener, IEvaluationRepository evaluationRepository)
    {
        this._context = context;
        _context.TraceListener = traceListener;
        _evaluationRepository = evaluationRepository;
        _evaluationRepository.Context = _context;


        _context.BeginTransaction();
    }


    public void Commit()
    {
        this._context.Commit();
    }

    public void Rollback()
    {
        this._context.Rollback();
    }

    protected virtual void Dispose(bool isDisposing)
    {
        if (!_isDisposed)
        {
            if (isDisposing)
            {
                if (_context != null)
                {
                    _context.Dispose();
                }
            }
            _isDisposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

So following would make no sense (as far as I understand the UWP lifecycle):

sealed partial class App : PrismUnityApplication
{
    public IEventAggregator EventAggregator { get; set; }

    protected override Task OnInitializeAsync(IActivatedEventArgs args)
    {
        var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");
        var con = new SQLiteConnection(new SQLitePlatformWinRT(), dbPath);
        // ommited
        Container
            .RegisterType<IUnitOfWork, UnitOfWork>(new ContainerControlledLifetimeManager(),
                new InjectionConstructor(con, new DebugTraceListener(), Container.Resolve<IEvaluationRepository>()));

    }

}

I am not really sure how to put this all together or if this even makes sense in my MVVM context. I would really open that all methods use the same DB Connection and ensure that connections are kept open for only a short time if possible. I have thought of an approach like this, e.g. if an action like "create object" is triggered (simplified example):

public class MainPageViewModel : ViewModelBase
{
    public MainPageViewModel()
    {
    }

    public void DoWork()
    {
         using (var uow = new UnitOfWork(new SQLiteConnection(new SQLitePlatformWinRT(), dbPath), new DebugTraceListener(), Container.Resolve<IEvaluationRepository>()))
        {
            //DoWork (Example)
            uow.EvaluationRepository.Insert(new Evaluation());
            uow.Commit();
        }
    }
}

However, I am not sure if this is the best approach – assuming I might to work on my data model through different ViewModels at the same time. What is your take on that? How could I ensure short-time DB connections in the UWP/MVVM context in a neat way?

\$\endgroup\$
1
\$\begingroup\$

What you should consider is some sort of DbContext (much like Entity Framework). You can define your connection within the DbContext, then just instance it and create a private static DbContext _activeContext field, then:

public class MyDbContext : IDisposable
{
    private static MyDbConnection _activeConnection;

    protected MyDbConnection ActiveConnection
    {
        get
        {
            if (_activeConnection == null)
            {
                // Set active connection and connect
            }

            return _activeConnection;
        }
    }
}

Then whenever you need it:

using (var context = new MyDbContext())
{
    // Use the UoW in the `MyDbContext` here
}

Obviously this is a lot of pseudo-code, but you should get the idea.

Then, any time you need MyDbContext, you may or may not actually be reconnecting.

Other than that: a lot of your code uses this._context when _context will suffice. You also have moderately poor naming (con, uow), that's the biggest issue I see here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.