c# - Using interfaces in models with SQLite -
let's have interface this:
public interface iuser { int id { get; } string name { get; } list<imonthlybudget> monthlybudget { get; } }
and have model implements this:
public class user : iuser { public int id { get; set; } public string name { get; set; } public list<imonthlybudget> monthlybudget { get; set; } }
and here have imonthlybudget:
public interface imonthlybudget { int id { get; } float monthlymax { get; } float currentspending { get; } float monthlyincome { get; } }
now have models. issue comes using sqlite. sqlite can't understand real implementation of imonthlybudget. understand why, don't want remove interface , expose real implementation clients use these models. in project structure have core project has model interfaces, , model implementation in data access project.
is there wrong how i'm approaching problem? assume i'm not first 1 run issue this. isn't normal practice keep model interfaces (what repositories etc use return types, parameters , stuff that) , implement actual concrete models in data access project?
and can explain why can't this:
public class user : iuser { public int id { get; set; } public string name { get; set; } public list<monthlybudget> monthlybudget { get; set; } }
monthlybudget implements imonthlybudget, shouldn't fine use concrete model type instead of the interface when concrete model implements interface?
a few questions here, i'll break down sections:
use of interfaces
it practice interface classes perform operations. example, may have data service (i.e. data access layer) interface allows operations read , modify data in persistent store. however, may have several implementations of data service. 1 implementation may save file system, dbms, mock unit testing, etc.
however, in many cases not need interface model classes. if you're using anemic business object approach (as opposed rich business objects), model classes in general should containers data, or plain old clr objects (poco). meaning these objects don't have real functionality speak of , don't reference special libraries or classes. "functionality" put in poco 1 dependent upon itself. example, if have user object has firstname , lastname property, create read-only property called fullname returns concatenation of two. pocos agnostic how populated , therefore can utilized in implementation of data service.
this should default direction when using anemic business object approach, there @ least 1 exception can think of may want interface models. may want support example sqlite data service, , realm (nosql) data service. realm objects happen require models derive realmobject. so, if wanted switch data access layer between sqlite , realm have interface models doing. i'm using realm example, hold true if wanted utilize models across other platforms, creating observable base class in uwp app example.
the key litmus test determining whether should create interfaces models ask question:
"will need consume these models in various consumers , consumers require me define specific base class models work in consumers?"
if answer "yes", should make interfaces models. if answer "no", creating model interfaces extraneous work , can forego , let data service implementations deal specifics of underlying data stores.
sqlite issue
whether continue use model interfaces or not, should still have data access implementation sqlite knows it's dealing sqlite-specific models , can crud operations directly on specific implementations of model. since you're referring specific model implementation, sqlite should work usual.
type compatibility
to answer final question type system not see this...
list<imonthlybudget> monthlybudget
as being type-compatible this...
list<monthlybudget> monthlybudget
in our minds seems if have list of apples, should type-compatible list of fruit. compiler sees apple type of fruit, not list of apples type of list of fruit. can't cast between them this...
list<imonthlybudget> mymonthlybudget = (list<imonthlybudget>) new list<monthlybudget>();
but can add monthlybudget object list of imonthlybudget objects this...
list<imonthlybudget> mymonthlybudget = new list<imonthlybudget>(); mymonthlybudget.add(new monthlybudget());
also can use linq .cast() method if want cast entire list @ once.
the reason behind has type variance. there's article on here can shed light why:
i hope helps! :-)
Comments
Post a Comment