3 tier app - navigation properties - c#

I'd using 3 tier architecture on my web project.
DAL -> EF 4 wrapper with classic CRUD method (AddEntity, RemoveEntity adn so on)
BAL -> business logic and query exposing (selectByName, byCity, bySomeOtherProperty).
UI - Aspx page
My problem is about navigationProperty exposed by EF. If I have a CustomerRepostiory, aspx side I don't want allow operation on entity that are not Customer, supposing follwing POCO class:
public class Customer
{
public int Id {get; set;}
public string Name {get; set;}
public ICollection<Orders> Order{get;set;}
}
and on aspx you execute something like this:
var customer = bll.getCustomerByName("alex");
customer.Order.Add(new ..) // BAD, I don't want allow it
What should I do? Maybe I must create a poco class wrapper in order to "hide" some properties?
Which really is best approach?

Expose your collection as an IEnumerable instead, that way the collection will be read only
You would have to do something like:
class Customer
{
private List<Order> orders();
Customer()
{
this.orders = new List<Order>();
}
public IEnumerable<Order> Orders { get { return this.orders.AsEnumerable(); } }
// you will need a public method to mutate the collection
public void AddOrder(Order order)
{
// implement custom logic, fire domain events, etc
this.orders.Add(order);
}
}
EDIT:
If you cannot modify your entity (which seems odd to me...) you could try to use the ObservableCollection<>
Something odd like this
class MyCustomer : Customer
{
private ObservableCollection<Order> orders;
internal bool AllowMutateCollection;
public MyCustomer()
{
this.Orders = this.orders = new ObservableCollection<string>();
this.orders.CollectionChanged += (_, __) =>
{
if(!this.AllowMutateCollection)
{
throw new NotImplementedException();
}
};
}
}
Now you would have to set the AllowMutateCollection when you will allow to mutate your entity, which becomes a real pain and probably this will be cause of some bugs... I do not recommend it
However I would strongly recommend you to redefine a little bit your design, wrapping your class and expose an IEnumerable instead, that would be cleaner and easier to maintain
Check this question
Fire an event when Collection Changed (add or remove)

Write a subclass for Customer, override Orders, make the getter do whatever access right checking you want

Related

Configure EntityFramework 6 to construct navigation properties for me?

I'm using EF6 Code First, I have a sample class
public class Department
{
public Department()
{
Workers = new List<Employee>();
}
public int Id { get; set; }
public virtual List<Employee> Workers { get; set; }
}
Do I really need that horrible constructor there?
I mean, the collection will not construct itself by magic, but I write code in such a way that all EF entities are always proxies (using Create() on DbSets when I need a new object). So I first expected for those "lazy" properties just to initialize themselves. After all, that's what proxies are for, I do these kind of things with Castle.Proxy, for example. But it seems that this functionality is not included in EF, or am I wrong?
I know I can write my own monstrous-looking property for lazy initialization of this collection, and then copy it everywhere I go, but I might as well be stuck with putting it all in the constructor. My goal is for my POCOs to look Plain.
Maybe there is a way to write some custom interceptor that will first initialize the collection if it is null?

Where to create the class

I'm trying to model a production system with "facility" as Class and some subclasses down to "Activity". The facility has a name as only parameter (at the moment), and I'd like to create an instance of the class reading the name as an input from a textbox. Since "activity" is inherit the properties from it's "parent classes" I'll create an instance of the class "activity" and not it's parent.
The problem is that I don't know where to create the class and how to pass it so that when I add the first subclass "Workstation" I can edit the properties of the same "activity" I created earlier.
I don't really have any code to add at this point unfortunately, but please tell me if there's anything special you'd like to see and I'll try to add it to the post.
And by the way, it's in the shape of a WinForm application with a GUI I'm trying to do this.
There are a couple things to note here. First, you'll want to use the Composite pattern to encapsulate the relationships between your classes. (For those who don't understand the OP's type hierarchy, it does make perfect sense in a factory context. There are many activities going on, which can be grouped into workstations and at a higher level into facilities.)
So, you should probably have a base Activity class (that supports the Composite pattern by exposing a collection of child activities), and then your "levels" (like Facility and Workstation) will inherit from Activity. Each of these classes will have unique properties.
The following classes should be created in their respective files, e.g. Activity.cs, Factory.cs, Workstation.cs:
class Activity
{
// An attribute that every Activity may need: a displayable name.
// This might be useful if you have a TreeView, e.g., showing all the activities.
public string Name { get; private set; }
// Every Activity could have child activities - this is the Composite pattern.
// You can loop through these to navigate through the hierarchy of your data.
// (This is often done using recursion; see example below with GetAllWorkstations().)
public List<Activity> ChildActivities { get; private set; }
public Activity()
{
ChildActivities = new List<Activity>();
}
public override string ToString() { return Name; }
}
class Factory : Activity
{
public string City { get; private set; }
public string Address { get; private set; }
}
class Workstation : Activity
{
public string WorkstationNumber { get; private set; }
}
The responsibility of loading your model then has to be handled somewhere. A good place to do it is in your main form. For example, you might write code like this:
class MainForm : Form
{
private readonly List<Factory> topLevelFactoryActivities;
public MainForm()
{
// ... other code
topLevelFactoryActivities = LoadTopLevelFactoryActivities();
}
private IEnumerable<Factory> LoadTopLevelFactoryActivities()
{
var factories = new List<Factory>();
// TODO: Load the factories, e.g. from a database or a file.
// You can load all the child objects for each factory here as well,
// or wait until later ("lazy-loading") if you want to.
// NOTE: If this becomes complex, you can move the LoadTopLevelFactoryActivities()
// method to its own class, which then becomes your "data access layer" (DAL).
return factories;
}
}
Now, if you want to find all the workstations that are part of a particular factory, you would write a method like the following on the Factory class:
class Factory : Activity
{
// ... other code
public IEnumerable<Workstation> GetAllWorkstations()
{
return GetWorkstationsRecursive(this);
}
private IEnumerable<Workstation> WorkstationsIn(Activity parentActivity)
{
foreach (var workstation in parentActivity.ChildActivities.OfType<Workstation>)
{
// Uses a C# feature called 'iterators' - really powerful!
yield return workstation;
}
foreach (var childActivity in parentActivity.ChildActivities)
{
// Using recursion to go down the hierarchy
foreach (var workstation in WorkstationsIn(childActivity))
{
yield return workstation;
}
}
}
}
You would call it like so, e.g. in your main form:
class MainForm : Form
{
// ... other code
public MainForm()
{
// ... other code
// Assume this is assigned to the factory that you want to get all the workstations for
Factory myFactory;
var workstations = myFactory.GetAllWorkstations();
// Now you can use 'workstations' as the items source for a list, for example.
}
}
As an example use case, you might want to show a second form (that belongs to the main form) which shows a list of all the workstations. (In practice you probably shouldn't create too many windows; prefer building a nonoverlapping layout. But just to show how you might pass the model instances around...)
class WorkstationListForm : Form
{
private IEnumerable<Workstation> workstations;
public WorkstationListForm(IEnumerable<Workstation> workstations)
{
this.workstations = workstations;
//TODO: You can now use 'workstations' as the ItemsSource of a list view in this form.
}
}
You could, of course, make topLevelFactoryActivities public on your MainForm and pass the variable this of the MainForm to the WorkstationListForm constructor instead. Then you could access the member on MainForm like this:
public WorkstationListForm(MainForm mainForm)
{
var topLevelFactoryActivities = mainForm.topLevelFactoryActivities;
// Now WorkstationListForm has full access to all the data on MainForm. This may or
// may not be helpful (it's usually best to minimize sharing and public fields).
}
Second, you'll want to use a proper separation between your view (user interface code/classes) and your model (the Activity hierarchy).
Third, if there's going to be any kind of live data being pushed to the user interface then you'll need a databinding mechanism to automatically update the view whenever the model changes.
In general, #2 & #3 are popularly addressed via the Model-View-ViewModel pattern. There is an excellent tutorial here for building an MVVM app using WinForms/C#.
That should get you started, at least. Also see an answer to a similar question. (Sorry about promoting my own answer, but I don't want to type out the whole example twice. Please forgive me. :))

C# bank example - class for customers - what for withdrawls, deposits, etc

I'm learning C# and am trying to get my head around when to use classes and when not to.
If I was writing an app for a bank, I know I would use classes for customers which would include their name, account number, balance, etc. Would I use a static class for the methods that would deposit into their account, withdraw, change their address, etc since I only need to write them once?
Also, what would I use to keep track of every customer object? Having 2,000 Customers:
exampleName = new Customer();
in my code doesn't seem right. I'm not at the point of learning database's yet and am just learning classes.
Having a database would be ideal, but in the mean time you could use an IEnumerable to hold your Customer objects, like this:
List<Customer> myCustomers = new List<Customer>();
myCustomers.Add(new Customer {Name = "Bob", Address = "123 Anywhere St." });
Then you can just pass the list around where needed.
Typically you will then have a property on the Customer class that holds the accounts:
public class Customer
{
public Customer()
{
_accounts = new List<Account>();
}
public List<Account> Accounts
{
get { return _accounts; }
set { _accounts = value; }
}
private List<Account> _accounts;
}
And so on. Note that I'm keeping this simple and doing things the more long winded and descriptive way as you are a beginner.
Using lists of items in this way is a good way to start because you will natuarlly use these when you get to using a database; you will retrieve result sets from the database and then translate those result sets into lists of business objects.
As for using static methods to do business logic like adjusting balances, changing addresses, etc., for you at this stage it doesn't matter. If you are using tools like Resharper it will nag you with suggestions like that, but in your case you can safely ignore that particular one. What you should look for is keeping everything as self contained as possible, avoid leakage of data and leakage of responsibilities between objects - this is just good coding discipline and a good way to prevent bugs that are caused by loose coding.
Once you've got your functionality laid down and working, you may have a desire to move some functionality into static 'helper' style classes. This is absolutely fine, but do be careful - helper classes are fantastic and everything but can quickly turn into an anti-pattern if you don't maintain that coding discipline.
You don't need to use a static class, or static methods, in order to only write the methods once. It may or may not make sense to do so, but this is a perfectly valid way to write the methods without repeating yourself:
public class Customer
{
//properties, constructors, etc.
public virtual void Deposit(decimal amount) { }
public virtual void Withdraw(decimal amount) { }
//etc
}
This also allows you to make use of polymorphism, e.g.
public class BusinessCustomer : Customer
{
public override void Deposit(decimal amount) { //some other implementation }
}
Static classes are used when you aren't going to instantiate objects. You get one "instance" of that class - you can't do things like:
MyStaticClass m = new MyStaticClass();
m.SomeFunc();
when you've got a static class. Instead you'd use it by using the class name itself. Something like:
MyStaticClass.SomeFunc();
As to what would you use to keep track of every Customer object? You could use some sort of collection to hold these. Granted, in a real system there'd be some sort of persistence piece, likely a database, to hold the data. But you could just make something like:
IEnumerable<Customer> Customers = new List<Customer>();
And then add your customers to that list
Customers.Add(new Customer() { ... });
Back to the question about static methods...
So, the deal here is that you're not going to be referencing instance members in a static method, so you wouldn't use static methods to update a particular Customer's address. Assuming your Customer class looked like:
public class Customer
{
public string Address { get; set; }
}
You couldn't use a static method like
public static void SetAddress()
because each Customer (presumably) has a different address. You couldn't access the customer's address there because it isn't static. Get that? Instead, you'd use a static method if you were wanting to do something that didn't need to deal with instance data. I use static methods for things like utility functions.
public static double ComputeSomething(double someVal) { ... }
Here, the ComputeSomething function can be called by anybody like:
var result = MyStaticClass.ComputeSomething(3.15);
The takeaway here is that static classes aren't used to instantiate objects, rather they are used really as a convenient container to hold functions. Static functions are ones that can be on a non-static class but can't access any of the instance data.
One place where a static function would be used would be for the Singleton pattern. You make the constructor non-public so folks can't call it, and instead provide a static method on the class to return the one and only instance of the class. Something like:
public class MySingleton
{
private static MySingleton instance;
private MySingleton() {}
public static MySingleton Instance
{
get
{
if (instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
}
what for withdrawls, deposits, etc
Those would be called Transactions.
This is meant to be in addition to the other answers. This is example of polymorphism with interfaces.
public interface IDeposit {
void Deposit(decimal amount);
}
public interface IWithdraw {
void Withdraw(decimal amount);
}
public class Customer : IDeposit, IWithdraw {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
public void Withdraw(decimal amount) { throw new NotImplementedException(); }
}
public class DepositOnlyATM : IDeposit {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
}
Keeps concepts separate, and allows for implementing multiple interfaces, or just one. With class inheritance approaches you only get one, and you get all of it. Inevitably you end up with spaghetti in my experience because sub-classes want some of the behavior, but not all of it.
I would recommend instead of getting into the implementation details right away that you first write down some simple user stories for your bank example. For instance
As a customer I would like to open a new account so that I can make deposits and withdrawls
Just in that requirement, we can envision a couple of classes (customer and account). From there just functionally decompose what the customer should do and what the account should do.
I've found that the book "The Object Oriented Thought Process" is a good read and will help answer some of the questions as to "when do I do this vs. that".
Good luck and have fun!

3 Tier application with singleton Pattern

I am Just creating a 3 Tier WinForm Application with following pattern.
-- MY BASE CLASS : DAL Class
public class Domain
{
public string CommandName = string.Empty;
public List<Object> Parameters = new List<Object>();
public void Save()
{
List<Object> Params = this.SaveEntity();
this.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Delete()
{
List<Object> Params = this.DeleteEntity();
this.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Update()
{
List<Object> Params = this.UpdateEntity();
this.ExecuteNonQuery(CommandName, Params.ToArray());
}
protected virtual List<Object> SaveEntity()
{
return null;
}
protected virtual List<Object> UpdateEntity()
{
return null;
}
protected virtual List<Object> DeleteEntity()
{
return null;
}
public int ExecuteNonQuery(string SqlText, params object[] Params)
{
/*
* Code block for executing Sql
*/
return 0;
}
}
My Business Layer Class which is going to inherit DLL Class
-- MY Children CLASS : BLL CLASS
public class Person : Domain
{
public string name
{
get;
set;
}
public string number
{
get;
set;
}
protected override List<object> SaveEntity()
{
this.Parameters.Add(name);
this.Parameters.Add(number);
return this.Parameters;
}
}
-- USE
This is way to use my Base Class
void Main()
{
Person p = new Person();
p.name = "Vijay";
p.number = "23";
p.Save();
}
Questions
Is this the right architecture I am following and Is there any chance to create the base class as Singleton?
Is there any other batter architecture?
Is there any pattern I can follow to extend my functionality?
Kindly suggest.
Lets see. I would try to give my input.
What I see here you are trying to do is ORM. So please change the name of base class from Domain to something else
Is this the right architecture I am following and Is there any chance to create the base class as Singleton?
Why do you need you base class as singleton. You would be inheriting your base class and you would create instances of child classes. Never ever you would be creating a instance of base itself.(99% times :) )
Is there any other batter architecture?
Understand this. To do a certain thing, there could be multiple ways. Its just the matter of fact, which one suits you the most.
Is there any pattern I can follow to extend my functionality?
Always remember the SOLID principles which gives you loose coupling and allow easy extensibility.
SOLID
There are couple of changes that I would suggest. Instead of a base class, start with Interface and then inherit it to make an abstract class.
Also make sure your base class can do all the CRUD functionality. I do not see a retrieval functionality here. How are you planning to do it? Probably you need a repository class that returns all the entity of your application. So when you need person, you would just go on ask the repository to return all the Person.
All said and done, there are lots of ORM tool, that does this kind of functionality and saves developer time. Its better to learn those technologies. For example LINQ - SQL.
Is this the right architecture I am following
There is no architecture which is optimal for any problem without context. That said, there are things that you can do to make your life more difficult. Singleton is not your problem in your implementation.
Is there any other batter architecture?
Probably, yes. Just glimpsing at the code, I see quite a lot of stuff that is going to hurt you in the near and not so near future.
First, a piece of advice: get the basics right, don't run before you can walk. This may be the cause for the downvotes.
Some random issues:
You are talking about 3-Tier architecture, but there are technically no tiers there, not even layers. Person doesn't look like business logic to me: if I understood correctly, it also must supply the string for the commands to execute, so it has to know SQL.
Empty virtual methods should be abstract. If you want to be able to execute arbitrary SQL move this outside the class
As #Anand pointed out, there are no methods to query
CommandName and Parameters are exposed as fields instead of properties
CommandName is not a Name, Domain doesn't look like a fitting name for that class
It looks like an awkward solution to a well-known problem (ORM). You say that you want to be able to execute custom SQL but any decent ORM should be able to let you do that.
Suggested reads: Code Complete for the basic stuff and Architecting Applications for the Enterprise for some clarity on the architectural patterns you could need.
As suggested by Anand, I removed all SQL related functions from my base class and put them all in another class, Sql.
Following that, I made the Sql class into a singleton. And I stored the Sql instance in BaseDAL so it can be accessible in all DAL class.
My code looks something like this
public class BaseDAL
{
// Singleton Instance
protected Sql _dal = Sql.Instance;
public string CommandName = string.Empty;
public List<Object> Parameters = new List<Object>();
public void Save()
{
List<Object> Params = this.SaveEntity();
_dal.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Delete()
{
List<Object> Params = this.DeleteEntity();
_dal.ExecuteNonQuery(CommandName, Params.ToArray());
}
public void Update()
{
List<Object> Params = this.UpdateEntity();
_dal.ExecuteNonQuery(CommandName, Params.ToArray());
}
protected virtual List<Object> SaveEntity()
{
return null;
}
protected virtual List<Object> UpdateEntity()
{
return null;
}
protected virtual List<Object> DeleteEntity()
{
return null;
}
// Other functions, like DataTable and DataSet querying
}
And the new SQL class is
public class Sql
{
// All other functions are also present in this class for DataTable DataSet and many other
// So this class is more then enough for me.
public int ExecuteNonQuery(string SqlText, params object[] Params)
{
// Code block for executing SQL
return 0;
}
}
CommandName and Parameters are exposed as fields instead of properties. In the original solution, they were properties. Also, I have a method in BaseDAL to query data so to help with implementing the Person class.

How to update MVVM nested ViewModels when Model changes and vice versa?

I'm looking for some advice on how to solve a problem which is bugging us at the moment.
Let's say we have a couple of business objects (POCOs) like
public class UserGroup
{
public virtual ICollection<Person> People { get; set; }
}
public class Person
{
public virtual ICollection<Adress> Adresses { get; set; }
}
public class Adress
{
public virtual string StreetName { get; set; }
}
This is a bit simplistic but I hope it's enough so that you get the idea. UserGroup has a collection of Person instances and each Person instance has a collection of Address instances.
The ViewModel for the UserGroup POCO could possibly look like this:
public class UserGroupViewModel
{
private UserGroup userGroupModel;
public UserGroup UserGroupModel
{
get { return this.userGroupModel; }
set
{
this.userGroupModel = value;
this.PeopleViewModelCollection =
new ObservableCollection<PeopleViewModel>();
foreach (Person p in this.UserGroupModel.People)
{
var personViewModel = new PersonViewModel();
personViewModel.PersonModel = p;
this.PeopleViewModelCollection.Add(personViewModel);
}
}
}
public ObservableCollection<PersonViewModel> PersonViewModelCollection
{
get;
set;
}
}
Where as the ViewModel for the Person POCO could look like this:
public class PersonViewModel
{
private Person personModel;
public Person PersonModel
{
get { return this.personModel; }
set
{
this.personModel = value;
this.AddressViewModelCollection =
new ObservableCollection<AddressViewModel>();
foreach (Address a in this.PersonModel.Adresses)
{
var addressViewModel = new AddressViewModel();
addressViewModel.AddressModel = a;
this.AdressViewModelCollection.Add(addressViewModel);
}
}
}
public ObservableCollection<AddressViewModel> AddressViewModelCollection
{
get;
set;
}
}
Again it is overly simplistic but what I want to show is that ViewModels have ObserableCollections of other ViewModels nested inside them.
The setter of the respective Model property, e.g. PersonViewModel.PersonModel does create ViewModels for all the adresses of the Person and adds them to the ObservableCollection<AdressViewModels> AdressViewModelCollection property of the PersonViewModel.
At this point we could use this code to display these ViewModels in a View. We can e.g. display the StreetName of a Person's Adress.
Now what should you do when you delete an Adress of a Person? Removing the AdressViewModel from the PersonViewModel.AdressViewModelCollection will update the GUI but it actually does not allow to update the underlying models.
Similar to that if you add another Adress to a Person Model the existing ViewModels are not going to reflect this change since the PersonViewModel.AdressViewModelCollection would only be rebuilt once the PersonViewModel.PersonModel property is set again.
Is it there a (preferably easy) way to achieve this two-way update between ViewModel and Model? Or maybe this is not advisable and it's better to handle this problem in a completely different way?
I'm keen to hear different opinions on this problem!
EDIT:
I would like to state that our model classes are generated by the Entity Framework 4.0 and are POCOs (see example of business objects above). I'm not sure if that was clear enough in the question itself. We would like to expose navigational properties (e.g. Person.Addresses) as ICollection<T>.
You could simplify things using dynamic proxies (e.g Castle.Proxy), take a look at this post for an idea how to accomplish this.
It sounds like it's not the cascading that is the issue. It's the synchronization between the model and view model.
You will need to listen to the observable collections collectionchanged event and an implementation is provided here.
I think your only option is to implement the INotifyPropertyChanged in your model since the entity framework doesn't provide a way to update your ViewModel.

Categories