In-Memory class without using database - c#

I have a concern. I want to know how can we make use of in-memory class in c# .Net using MVC 4 in Visual Studio 2010. i mean to say i do not want to use database or any other external storage medium even repository.
I want to store Data, retrieve data from that class.
I heard about "Caching" but it have its own limitations.
I also not to use any type of repositories, because using repository, i have made already using http://www.edandersen.com/2013/05/30/asp-net-mvc-basics-part-2-viewmodel-to-model-mapping-and-editing/.
So can you suggest me how to do this?

What's your goal?
If the data is important to persist you can't have it in memory. IIS apps can restart at any time due to many reasons. The data is then lost without notice.
If the data is meant as a cache either use indeed a cache or a static variable (with proper synchronization).

You could use a static object instance. For example, let's say that you have a User class:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
and then have a static container for your entities:
public static class Container
{
static Container()
{
Users = new ConcurrentBag<User>();
}
public static IEnumerable<User> Users { get; set; }
...
}
And then you can access this static instance from anywhere in your code. Obviously since ASP.NET MVC is a multithreaded environment you will need to properly synchronize the access to those variables. For example using ConcurrentBag<User> instead of a List<User> implementation.
and then in your controller you could access your in-memory data store:
public ActionResult Index(int id)
{
var user = Container.Users.FirstOrDefault(x => x.Id == id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}

Related

Domain Model and related data (anemic domain model)

I'm currently working with ASP .NET Core 1.0 using Entity Framework Core. I have some complex calculations with data from the database and I'm not sure how to build a proper architecture using Dependency Injection without building an anemic domain model (http://www.martinfowler.com/bliki/AnemicDomainModel.html)
(Simplified) Example:
I have the following entities:
public class Project {
public int Id {get;set;}
public string Name {get;set;}
}
public class TimeEntry
{
public int Id {get;set;}
public DateTime Date {get;set;}
public int DurationMinutes {get;set;}
public int ProjectId {get;set;}
public Project Project {get;set;}
}
public class Employee {
public int Id {get;set;}
public string Name {get;set;}
public List<TimeEntry> TimeEntries {get;set;}
}
I want to do some complex calculations to calculate a monthly TimeSheet. Because I can not access the database within the Employee entity I calculate the TimeSheet in a EmployeeService.
public class EmployeeService {
private DbContext _db;
public EmployeeService(DbContext db) {
_db = db;
}
public List<CalculatedMonth> GetMonthlyTimeSheet(int employeeId) {
var employee = _db.Employee.Include(x=>x.TimeEntry).ThenInclude(x=>x.Project).Single();
var result = new List<CalculatedMonth>();
//complex calculation using TimeEntries etc here
return result;
}
}
If I want to get the TimeSheet I need to inject the EmployeeService and call GetMonthlyTimeSheet.
So - I end up with a lot of GetThis() and GetThat() methods inside my service although this methods would perfectly fit into the Employee class itself.
What I want to achieve is something like:
public class Employee {
public int Id {get;set;}
public string Name {get;set;}
public List<TimeEntry> TimeEntries {get;set;}
public List<CalculatedMonth> GetMonthlyTimeSheet() {
var result = new List<CalculatedMonth>();
//complex calculation using TimeEntries etc here
return result;
}
}
public IActionResult GetTimeSheets(int employeeId) {
var employee = _employeeRepository.Get(employeeId);
return employee.GetTimeSheets();
}
...but for that I need to make sure that the list of TimeEntries is populated from the database (EF Core does not support lazy loading). I do not want to .Include(x=>y) everything on every request because sometimes I just need the employee's name without the timeentries and it would affect the performance of the application.
Can anyone point me in a direction how to architect this properly?
Edit:
One possibility (from the comments of the first answer) would be:
public class Employee {
public int Id {get;set;}
public string Name {get;set;}
public List<TimeEntry> TimeEntries {get;set;}
public List<CalculatedMonth> GetMonthlyTimeSheet() {
if (TimeEntries == null)
throw new PleaseIncludePropertyException(nameof(TimeEntries));
var result = new List<CalculatedMonth>();
//complex calculation using TimeEntries etc here
return result;
}
}
public class EmployeeService {
private DbContext _db;
public EmployeeService(DbContext db) {
_db = db;
}
public Employee GetEmployeeWithoutData(int employeeId) {
return _db.Employee.Single();
}
public Employee GetEmployeeWithData(int employeeId) {
return _db.Employee.Include(x=>x.TimeEntry).ThenInclude(x=>x.Project).Single();
}
}
public IActionResult GetTimeSheets(int employeeId) {
var employee = _employeeService.GetEmployeeWithData(employeeId);
return employee.GetTimeSheets();
}
Do not try to solve querying problems with your aggregates. Your aggregates are meant to process commands and protect invariants. They form a consistency boundary around a set of data.
Is the Employee object responsible for protecting the integrity of an employee's timesheet? If it doesn't then this data doesn't belong into the Employee class.
Lazy-loading may be fine for CRUD models, but is usually considered an anti-pattern when we design aggregates because those should be as small and cohesive as possible.
Are you taking business decisions based on the calculated result from timesheets? Is there any invariants to protect? Does it matter if the decision was made on stale timesheet data? If the answer to these questions is no then your calculation is really nothing more than a query.
Placing queries in service objects is fine. These service objects may even live outside the domain model (e.g. in the application layer), but there is no strict rule to follow. Also, you may choose to load a few aggregates in order to access the required data to process the calculations, but it's usually better to go directly in the database. This allows a better separation between your reads & writes (CQRS).
If I understood your question correctly you can use a trick with injecting a service into your entities that helps it do the job, e.g.:
public class Employee()
{
public object GetTimeSheets(ICalculatorHelper helper)
{
}
}
Then in your service that holds the employees you would obtain it in the constructor and pass to the employee class for calculations. This service can be a Facade e.g. for getting all the data and perform initialization or whatever you really need.
As for the TimeEntries, you can get them using a function like this:
private GetTimeEntries(ICalculationHelper helper)
{
if (_entries == null)
{
_entries = helper.GetTimeEntries();
}
return _entries;
}
It depends of course on you strategy of caching and so on if this pattern fits you.
Personally I find it rather easy to work with anemic classes and have a lot of the business logic in services. I do put some in the objects, like e.g. calculating FullName out of FirstName and LastName. Usually stuff that does not involve other services. Though it's a matter of preference.

Supporting multiple database's - returning common object from query's

I am trying to create an app the can handle multiple database types.
So far I have created my Interface like so. Its very simple and all the database will do is Load and Save a profile
public interface IDataManager
{
Profile LoadProfile(int profileId);
bool SaveProfile(Profile profile);
bool CreateDatabase();
bool OpenConnection();
bool CloseConnection();
}
and lets just say the Profile class for the above looks like this.
public class Profile
{
public int Id { get; set; }
public string Name { get; set; }
}
My question is what is the best way to make it so that all the implementations of IDataManager return the same object types?
Here is an example of what I mean by this. (This is not quality code its just an example)
I create an SQLite class that implements IDataManager and then create an instance.
public IDataManager DataManager = new SQLiteDataManager();
Later in the code I want to load a Profile so I call the LoadProfile.
Profile profile = DataManager.LoadProfile(1);
My SQLite implementation of the LoadProfile method looks like this
public Profile LoadProfile(int profileId)
{
// Copied and pasted from a WinRT app
using (var conn = new global::SQLite.Net.SQLiteConnection(new global::SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), _sqlpath))
{
var tmp = conn.Table<PROFILE>().First(x => x.ID == profileId);
}
// do something and return
}
Now as you can see the return type from the query (tmp = type PROFILE) is not the same type as the LoadProfile method return type (Profile).
Do I have to convert tmp to Profile? which means it must be done in all the methods with return types, and for every different database implementation. or is there a better way of doing this?
Hope this makes sense.
If you use Entity Framework you can just use the provider for the db type you will be using but keep all the api and models the same
A list of Entity Framework providers for various databases

How to store Active Directory user GUID using Entity Framework?

I have a site that authenticates using Active Directory. I am using the Entity Framework and I need to store references to this users. I don't want save AD users in the database. One way is to store the user guid as a String in an Entity.
class Entity
{
String UserGUID ;
}
Is it possible to something like this:
class Entity
{
UserPrincipal user;
}
Instead of passing the string GUID pass an object and make the Entity Framework treat the association somewhat as if it the UserPrincipal object was an entity. It doesn't have to be the class UserPrincipal, it could be a another class. I would like to deal with objects rather than strings. Querying Active directory is not a problem.
In summary, I would like to be able to associate an entity with a non-entity class by storing a String GUID in the database but loading it as an object.
[UPDATE]
Many classes might have multiple associations with the AD users and it can vary so a base class is not a solution. For example, I might have a class like this:
class Message
{
public User Sender;
public User Recipient;
public List<User> MentionedUsers;
}
This is not a class I am using but it illustrates my point. Ideally the User guid would be stored in the Message entity table but be loaded as a User just like the Entity Framework does with other entites.
I am thinking creating User as a wrapper entity class to the GUID and retrieve properties with static methods but I would like to avoid this.
Seems easy enough for code first:
public class Entity {
public string UserGUID { get; set; }
[NotMapped]
private UserPrincipal? _user;
[NotMapped]
public UserPrincipal User
{
get
{
if (!_user.HasValue)
_user = UserPrincipal.GetUser(this.UserGUID); // Make this static for easier re-use.
return _user.Value;
}
set
{
UserGUID = value.UserGUID;
_user = value;
}
}
}
[NotMapped] is your friend here (it's in System.ComponentModel.DataAnnotations). You could simplify things by simply returning the function call every time you user get, eg: get { return this.GetUser(); } and remove the _user field, but that would impact performance.
I'm also not sure if you need [NotMapped] on a field (in this case _user), I would try it with and without.
For a list of users:
public class Entity {
public List<string> UserGUIDs { get; set; }
[NotMapped]
private List<UserPrincipal> _users;
[NotMapped]
public List<UserPrincipal> Users
{
get
{
if (_users != null)
_users = UserPrincipal.GetUsers(this.UserGUIDs);
return _users;
}
set
{
this.UserGUIDs = value.Select(u => u.UserGUID).ToList();
_users = value;
}
}
}
Unfortunately there's not really a more elegant way to implement this with EF. Now, it wouldn't be all that difficult to alter EF to do this. EF is open source, fork it and get going if it's a big enough project to be worth it for you.

Persisting the state pattern using Entity Framework

I am currently developing a project in MVC 3. I've separated my concerns so there are projects such as Core, Repository, UI, Services etc. I have implement the Repository, UnitOfWork and most importantly the State pattern.
I am using Entity Framework 4.3 to persist my data and I have come across a rather annoying situation involving the persistence of the current state. Below are some class examples:
public class Request
{
public int RequestId { get; set; }
public State CurrentState { get; set; }
}
public abstract class State
{
[Key]
public string Name {get; set;}
public virtual void OpenRequest(Request request)
{}
public virtual void CloseRequest(Request request)
{}
}
public class RequestIsOpenState : State
{
public RequestIsOpenState()
{
this.Name = "Open";
}
public override void CloseRequest(Request request)
{
request.CurrentState = new RequstIsClosedState();
}
}
public class RequestIsClosedState : State
{
public RequestIsClosedState()
{
this.Name = "Closed";
}
public override void OpenRequest(Request request)
{
request.CurrentState = new RequstIsOpenState();
}
}
Using the above example I will get a primary key violation exception because it tries to create a NEW state in the States table.
Because the state change is done within the domain layer, I can't just 'get' the state from the repository and set it using the foreign key by doing something like this:
Request request = unitOfWork.RequestRepository.Find(1);
request.CurrentState = unitOfWork.StateRepository.Find("Closed");
I'm aware I have the option of not mapping the state property, and persist a string property in the request class and then convert them back and forth through a factory on a get and set when the entity is hydrated (see this answer).
All I want to do is persist the state class, so when the request is returned I can access the state methods immediately without having loads of EF stuff polluting my domain layer just to handle one persistence issue. Another benefit of which would be it gives me the added bonus of having a table in SQL to query against known states.
I think you can improve it by caching the State instances creating it only once, to avoid making the list each time and avoid the foreach:
public static class StateFactory
{
private static Dictionary<string, State> statesCache = FindAllDerivedStates();
public static State GetState(string stateTypeName)
{
return statesCache[stateTypeName];
}
private static Dictionary<string, State> FindAllDerivedStates()
{
var derivedType = typeof(State);
var assembly = Assembly.GetAssembly(typeof(State));
return assembly.GetTypes().Where(t => t != derivedType && derivedType.IsAssignableFrom(t))
.Select(t => (State)Activator.CreateInstance(t))
.ToDictionary(k => k.Name);
}
}
I've made some progress by simplifying the factory back to basics and by implementing it in such a way that you would never really know that a factory is being used. Although It's not what I was looking for, it is so refined and streamlined the only downside is I still don't have a list of ALL states within the SQL database, there are however many possible work arounds for this. Anyway... my compromise:
The State Factory:
public static State GetState(string stateTypeName)
{
var list = FindAllDerivedStates();
dynamic returnedValue = new NullState();
foreach(var state in list)
{
if(state.Name == stateTypeName) returnedValue = (State)Activator.CreateInstance(state);
}
return returnedValue
}
private static List<Type> FindAllDerivedStates()
{
var derivedType = typeof(State);
var assembly = Assembly.GetAssembly(typeof(State));
return assembly.GetTypes().Where(t => t != derivedType && derivedType.IsAssignableFrom(t)).ToList();
}
Now the request needs two properties, a persisted string and a State class. Make sure the State class is not mapped.
public class Request
{
public string StateString { get; set; }
[NotMapped] or [Ignore]
public State CurrentState
{
get
{
return StateFactory.GetState(this.StateString);
}
set
{
this.State = value.GetType().Name;
}
}
}
Now because of the new simplistic implementation, saving the state is as easy as;
request.CurrentState = new OpenState();
and getting the state will always return the methods. Without any extra work you can return an entity and excess the properties. For example if you want output the public string;
request.CurrentState.StateName;
Now I've still got to implement a little work around to add a list of states to my SqlDb but that's not the end of the world. It seems this is the only solution. Or should I say best solution. I'll keep my eyes peeled for a better version.

How many GET methods a service should have?

What are the best practices for writing a service layer methods that retrieves data from repository?
Let's say we have two models: Team and User (user is part of a team):
public class User {
public int Id { get; set; }
public string Name { get; set; }
public int TeamId { get; set; }
public virtual Team Team { get; set; }
public bool Active { get; set; }
}
public class Team {
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
}
If I want to write service to retrieve user data from repository by various conditions, do I have to write multiple methods to get a user e.g. getAll, getAllByName, getAllActiveByName, getAllActiveByTeamId, getAllActiveByNameAndTeamId, etc?
public IEnumerable<User> GetAll()
{
return _repository.GetAll();
}
public IEnumerable<User> GetAllActiveByName(string name)
{
return _repository.GetBy(u => u.Name == name && u.Active);
}
public IEnumerable<User> GetAllActiveByNameAndTeamId(string name, int teamId)
{
return _repository.GetBy(u => u.Name == name && u.Active && u.TeamId == teamId);
}
These are just simple examples but in real life we can end up having tens of service methods for different scenarios, when models are more complex.
Or maybe it is better to have one GetBy method that will return users based on the provided filter? I use Generic Repository Pattern and I could use GetBy method when implementing GetBy service method:
public IEnumerable<User> GetBy(Expression<Func<User, object>>filter )
{
return _usersRepository.GetBy(filter);
}
Having this I would not have to write tens of "duplicated" methods for all the scenarios.
Then it would be controller responsibility to set the filter:
public ViewResult Index(int teamId = 0){
//[...]
var users = _usersService.GetBy(u => u.IsActive && u.teamId == teamId);
//[...]
}
Any thoughts on that?
I'm of the opinion that you should have as many query methods as you have scenarios.
In that way you can optimize individual queries by for example using a precalculated view.
Some of your queries might use eager loading, other might use lazy loading...
Also, if you always return IQueryable how are you going to test it? Your service will have only one method GetAll and is so anemic that you can just get rid of it and use repository directly in the controller.
Another argument against GetAll is that any one can execute any query in the UI!
Consider reading about CQRS.
Or maybe it is better to have one getAll method that will return only
active users and then use lambda expression in the controller?
No. This kind of query will be good only for static data that too in-memory. Say you have some application level data and it is not going to change for certain time, then instead of querying it everytime, you getall for first time and then put in local server cache. Then use it for next simultaneous requests. But this approach is not going to for heavily changing dynamic data. Also performance of this query depends on number of records it is returning, so sometimes it might give very bad performance.
do I have to write multiple methods to get a user e.g. getAll,
getAllByName, getAllActiveByName, getAllActiveByTeamId,
getAllActiveByNameAndTeamId, etc?
Thats better. This approach will give you load on demand freedom, that means load necessary data when it is required, instead of getting all data and discarding it.

Categories

Resources