C# Service method interact with two similar domain classes - c#

I am working with an app that handles appointment scheduling.
Right now what I am doing is generating a list of people to call for confirmations in a confirmations section and a list of people to call for rescheduling in a rescheduling section.
I have two separate, but very similar (nearly identical) domain classes for the confirmation items and the rescheduling items.
I have two nearly identical methods in my scheduling service that handle list generation.
I would like to only use one method in the service that would handle the list generation for both of these. The only real difference between the two service methods is which table is being referenced.
My problem is that I can't dynamically change which domain class I am using based on what mode the user is interacting with (confirmations/rescheduling). I get a cannot implicitly convert type error.
I thought a solution would be to create a parent domain class "scheduling item" and have the confirmation item and scheduling item be children of that. However, I still can't figure out how to reference them in the service method.
I thought I could declare a var and then assign it to whichever domain I wanted based on the mode the user is in. That also gets an error because it wants the var's type to be declared in advance.
I am relatively new to C# and I could really use some advice on the best way to simplify this and not have two nearly identical sets of code.
I realize I could just use one class for both, but that would not be ideal, because I would like to keep the data separate for the two domains.
I cannot share the actual code. I figure with the information I have given though, someone might be able to tell me how to handle one service method for two related domain classes.
Thanks in advance for any help you can offer.
To clarify, our set up is like this:
There is a class ConfirmationItem and a class ReschedulingItem that are models for the Mongo database tables.
The Scheduling Service has two methods currently that are "GenerateConfirmationItemList"/"GenerateReschedulingItemList".
The way these methods access the data is like this:
var confirmationItems = GenericRepository.Table<ConfirmationItem>().Where(...).ToList();
var reschedulingItems = GenericRepository.Table<ReschedulingItem>().Where(...).ToList();
Other than these initial table references, the logic is identical.
What would be really helpful is if I could have the method choose which table to use based on what mode we are in (Confirmation or Rescheduling).
However, if I try something like:
var scheduling items;
switch(mode)
case "confirmation":
{
schedulingItems = GenericRepository.Table<ConfirmationItem>().Where(...).ToList();
}
This gets an error because implicitly typed vars have to be assigned.

Related

Using Entity Framework to return a table of data to iterate against

I am currently using EF 6 to do the following. Execute a stored procedure, then bring in the data I need to use. The data is usually 30-40 rows per application run.
I then iterate over the var, object, table (whatever you would like to call it), performing similar (sometimes different) tasks on each row. It works great. I am able to create an Entity object, expose the different complex functions of it, and then create a var to iterate over.
Like:
foreach (var result in StoredProcedureResult)
{
string strFirstname = result.FirstName
string strLastName = result.LastName
//more logic goes here using those variables and interacting with another app
}
I recently thought it would be cool if I had a class solely for accessing the data. In this way, I could just reference that class, toss the corresponding connection string into my app.config, and then I can keep the two sets of logic separate. So when attempting to do the above in that structure, I get to the point at which, you can't return a var, or when I attempt to match object return type. The return type of the execution of a stored procedure is object (which I can't iterate on).
So my question is, how does one get to the above example, except, the var result, get returned from this data access class?
If I am missing something, or its not possible because I am doing this incorrectly, do let me know. It appeared right in my head.
I'm not going to describe the architecture in full. But based on your comments you can do the following (this is not the definitive nor the only way how to do it):
in your data access project you keep the DBContext class, all the code for the stored procedure call and also the class that defines the result of the SP call, let's call it class A;
in your shared layer project - I would suggest calling it Service layer - you can create a XYService class, that has a method e.g. GetListOfX that connects to the DB and calls the procedure, if needed this method can also perform some logic, but more importantly: it doesn't return class A, but returns a new class B (this one is defined in the service layer, or can be defined in yet another project - that might be the true shared/common project; as it would be just a definition of common structures it isn't really a layer);
in your application layer you work only with the method GetListOfX of the XYService and the class B, that way you don't need a reference to the data access project
In a trivial case the class B has the same properties as the class A. But depending on your needs the class B can have additional properties/functionality it can also ignore some properties of A or even combine multiple properties into one: e.g. combining the FirstName and LastName as one property called simply Name.
Basically what you are looking for is the multi-tier application architecture (usually 3-4 tier). The full extent of such approach (which includes heavy usage of concepts like interfaces and dependency injection) might not be suitable or needed based on your goals, e.g. if you are building just a small application for yourself with a couple of functions or you know there won't be any reuse of the components of the final solution, then this approach is too wasteful and you can work faster with everything in one project - you should still apply principles like SOLID, DRY and Separation of concerns.

Looking for best way to refactor a large class

I have a situation whereby a predecessor has created a class that is designed to handle the creation of Note entities that are added to the database to journal actions that are carried out by the system across the site.
At present, this class has been broken down into several CreateXYZNote methods that take an enum denoting a specific note type, and an instance of the model that drives that area of the site.
My problem is, there are so many types of notes, each used only in one or two places across the system. Each of the methods is huge, consisting of a small amount of common code, and specifics (e.g. the textual content of the note) are held within a series of switch statements based on an enum. Extremely hard to find the code relating to specific notes, and very hard to maintain at present, and it's only going to grow as new types of notes find their way into the system over time.
Has anyone got any advice or patterns that could help with this sort of situation?
The simplest solution I can think of is that I have a set of profiles held outside of this class as a dictionary (keyed by the enum values) that define the title, description, categories etc. for the notes, and this class then becomes just a means of looking up those values and creating the note, but it just feels like I'm moving the problem to another place rather than resolving it.
You could use a NoteFactory that has a INote Create(NoteType type) method. The factory could depend on a Dictionary keyed by NoteType that the factory uses to find and return the appropriate Note. This way you avoid a non-OCP switch statement.
The factory can be injected with the dictionary, using an IoC container helps here, or you can create the dictionary in the constructor.

What is best practise for repository pattern - repo per table?

The repository pattern seems to work well when working with an initial project with several large main tables.
However as the project grows it seems a little inflexible. Say you have lots of child tables that hang off the main table, do you need a repository for each table?
E.g.
CustomerAddress Record has following child tables:
-> County
-> Country
-> CustomerType
On the UI, 3 dropdown lists need to be displayed, but it gets a bit tedious writing a repository for each of the above tables which selects the data for the dropdowns.
Is there a best practice/more efficient way of doing this?
As an example say you have a main CustomerAddress repository which I guess is the 'aggregate root' which inherits the main CRUD operations from the base repo interface.
Previously I have short-cutted the aggregate root and gone straight to the context for these kinds of tables.
e.g.
public Customer GetCustomerById(int id)
{
return Get(id);
}
public IEnumerable<Country> GetCountries()
{
return _ctx.DataContext.Countries.ToList();
}
etc...
But sometimes it doesn't feel right, as countries aren't part of the customer, but I feel like I need to tack it onto something without having to create zillions of repos for each table. A repo per table definately doesn't seem right to me either.
First the code you posted is not the repository pattern. Where is the collection like interface? If it is an aggregate it should only be returning the aggregate type.
Repository pattern doesn't offer up much flexibility when it comes being able to select different types. Repository pattern follows a collection interface (insert/add/update/delete/get/etc), mirroring an in memory thing, and it generally only retrieves on type. So if you were to use the repository pattern you would need to select all CustomerAddresses and then* filter the countries out. I would suggest you move to a different pattern, that allows for more flexibility aka DAO.
If these things are always going to be maintained through CustomerAddress, then switch patterns and create a DAO class that offers some other getters for the other types of things you need.
On a more generic note, build for need.
Never just blindly create repository classes, its a maintenance nightmare. The only time I would argue for a repo per table is when you are doing CMS like things, and need to be able create everything.
Example:
So you have a CustomerAddress which ties together a Customer and a Country, but you have some other process that needs to be able to CRUD the Country. As a result you need* the repository to manipulate Country and if you are following DRY you dont want to have duplicate logic to manipulate Countries. What you would have is a Customer Respotitory that uses the Country repository.
I'm answering my own question here because while the suggestions are certainly useful, I feel I have a better solution.
While I don't have to phsyically create the underlying repository for each and every table as I have a generic repository base class with interface (Get, Add, Remove), I still have to:
1) write the interface to access any specialised methods (generally these are queries)
2) write those implementations
I don't necessarily want to do this when all I want to retrieve is a list of countries or some simple type for populating a dropdown. Think of effort required if you have 10 reference type tables.
What I decided to do was create a new class called SimpleRepo with ISimpleRepo interface which exposes 1-2 methods. While I don't normally like to expose the IQueryable interface out of the repo i/f class, I don't mind here as I want the provided flexibility. I can simply expose a 'Query()' method which provides the flexibility hook. I might need this for specialising the ordering, or filtering.
Whenever a service needs to make use of some simple data, the ISimple< T > interface is passed in, where T is the table/class.
I now avoid the need to create an interface/class for these simple pieces of data.
Thoughts anyone?
Responding to the questioner's own answer: This doesn't make sense to me; though it's possible you still had a good use case, I'm not following. Points 1 and 2 ... if you need specialized methods, then looks like they belong in their own repo. Point 2: yes, that needs an implementation.
Sharing between repos, with the smaller repo being the question (is that one needed), I do appreciate that question / problem, but guys' on this thread steered me to being okay with 1 repo per table, including the possibility of having a 'service layer', though they didn't give any examples of that, and I haven't tried this out yet (currently my practice, for good or ill, has been to have the bigger repo share or instantiate the smaller one it needs):
One repository per table or one per functional section?

Adding arbitrary properties to a strongly typed list

I'm looking for a good way to add arbitrary properties to the objects in a strongly typed list, based on the principle that I shouldn't pass a DataTable from my business layer to my presentation layer.
For example, I might have a Category class with the properties CategoryId and Title. On one page I would like to fetch a list of all categories (ie. List<Category>) together with the most expensive product in each category.
A while ago, I would have just returned a DataTable with some additional columns in it with the product data in, but I'm trying not to do that -- it would be trivial to set up it's not good practice.
One option is to add a MostExpensiveProduct property to my Category class, but I might want to display the most recently added product in another case, or the cheapest product, so I'd end up adding a lot of properties to cover all the options. This just doesn't feel right to me.
Am I missing a trick here? What is the best way of doing this? Or should I just be returning a DataTable to which I can add as many columns as I need and not worry about it?
The issue seems to be you have a lot of different views you'd like to offer the user. The options I see are:
You could construct separate classes for each view that inherit from the Category class. Code gen would be a good solution here.
You could store an Attributes property, which has an IDictionary interface, and refer to items by key. I'm becoming a fan of this approach.
You could generate a data table only for binding purposes, for these views... or develop a data table like component where you can refer to fields by Key...
For fields that you compute (say you store sales tax and net price, and compute gross cost), you could store as a method of the Category object, or as an extension method.
I'm sure there are other options that I haven't thought about...
HTH.
You should create a specialized class (a view model) for each view you have containing only the properties you are interested in using in the view. This may seem like unnecessary duplication for the simplest cases, but pays off in terms of consistency and separation of layers. You can construct the view models manually, or if that gets tedious, use an object-object mapping framework like AutoMapper.
There are several things to consider here IMHO. First, it seems that the only reference from Category to Product should be Category.Products, meaning you should never have something like Category.MostExpensiveProdcut etc. As far as your business layer, I would do something like this:
From your code behind in the presentation layer:
call CategoryManager.GetCategories();
call List<Product>ProductManager.GetMostExpensiveProducts(List<Category>);
Now that you have a list of Categories, and a list of Products (assuming your Product has a reference back to its Category) you have all the necessary information to work with. Using this setup your entities (Category, Product) are not polluted.
Another thing to consider is introducing a services layer. If you find that you don't want (for whatever reason) to make two calls to the business managers, rather you want to make a single call and get all your information in one shot I would consider introducing a services layer sometimes aka "application facade". This facade would be responsible for making the individual calls to the business managers and combining results into one response before shipping it back to the UI layer. Someone mentioned that that custom object would be a "ViewModel", which is correct but often used in reference to MVC. Another name for it would be a DTO (Data Transfer Object), which designed for use with service layers/application facade.

C# classes and methods

I find it difficult to determine the responsiblity of classes: do i have to put this method in this class or should I put this method in another class? For example, imagine a simple User class with an id, forname, lastname and password. Now you have an userId and you want the forname and lastname, so you create a method like: public User GetUserById(int id){}. Next you want to show list of all the users, so you create another method: public List GetAllUsers(){}. And offcourse you want to update, delete and save a user. This gives us 5 methods:
public bool SaveUser(User user);
public bool UpdateUser(User user);
public bool DeleteUser(User user);
public User GetUserById(int id);
public List<User> GetAllUsers();
So my question is: do you put all these methods in the User class? Or do you create another data class (UserData class) which may connect to the database and contain all these methods?
What you are describing here is basically a choice between the Active Record Pattern or the Repository Pattern. I'd advise you to read up on those patterns and choose whichever one fits your application / experience / toolset.
I would not put those specific methods into the 'User' class.
There are 2 common approaches for this 'problem':
You put those method in the User
class, and then this means you 're
using the Active Record pattern
You put those methods in a
separate class (UserRepository) for
instance, and then you're using the
Repository pattern.
I prefer the repository-approach, since that keeps my 'User' class clean, and doesn't clutter it with data access code.
Barring additional complexity specific to a group of users (or really elaborate database access mechanics) I might make those methods static on the User class.
Those methods sound more like a UserManager (or something like that) to me. The user class should correspond to and represent only a single user, not many.
If we look at Enterprise Application design patterns, then the methods for fetching Users i.e. GetUserByID and GetAllUsers would be in separate class - you can name it UserData or UserDAO (DAO - Data Access Object).
Infact you should design an interface for UserDAO with appropriate methods for handling User Objects - such as CreateUser, UpdateUser, DeleterUser, GetUserXXX and so on.
There should be an implementation of UserDAO as per the data source, for example if your users are stored in database then you can implement the logic of accessing database in the implementation of UserDAO.
Following are the advantages of keeping the access methods in separate class:
1) User object should be plain object with just getter setter methods, this would facilitate passing object across tiers - from data access tier, to business tier to web tier. This would also help keep User Object serializable
2) The data access logic is loosely coupled from the User object - that means if the datasource changes, then you need not change the User object itself. This also assists in Test Driven Development where you might need to have mock objects during testing phase
3) If User object is complex object with relations with other objects such as Address or Department or Role etc. then the complexity of relationships will be encapsulated in UserDAO rather than leaking in the User Object.
4) Porting to frameworks like NHibernate or Spring.NET or .NET LINQ would become easier if the patterns are followed
Lets us see you scenario as this.
There are 'N' number of people working in assembly division of you company.
It is okay to go to a person and ask about his information BUT you cant expect him to tell you details of all persons working in assembly division. Reason why shud he remember all the details and if you do expect then his effeciency will go down(work on assembly and also remember details of others).
So ..... perhaps we can appoint a manager who can do this ppl maanagement activities
(get details, add new person, edit ,delete etc etc )
Therefore you have two entities
1) User/Person working in your assembly deivision
2) a Manager
Thus two classes. Hopes this will help you.
Thanks
If I understand your question correctly the User class deals with a single user. Hence the user class does not have a clue about how many users there are or anything about them. The structure holding this information is somewhere else and the methods you mention seem to belong to that structure / class.
With all else being equal either way is fine. Which to choose, though, usually depends on the overall architecture of the application or class library in which you find the User class. If the data access code seems tangled with the User object code, then it might make more sense to split it into two classes as you've considered. If the CRUD methods are one-line delegations to a DAL with maybe application-specific logic, then leaving them in the User class should be okay.
The complexity is more or less the same in both cases—it's a trade-off between a low-maintenace assembly with few high-maintenance classes or a high-maintenance assembly with a larger number of low-maintenance classes.
I'm also assuming that the CRUD methods should be static.
Do what's easiest to get the code written right now but consider possible refactorings in the future should you find that it'll be better that way.

Categories

Resources