I'm attempting to use the command pattern for the first time, and with it create a command factory, I'm following guidance from a pluralsight.com course where he implements an interface for the factory which includes a MakeCommand method.
Now my issue comes from the fact that he simply passes an array of string as the arguments for this method (his is a command line app), however my commands will use a variety of arguments of a variety of types, my plan was to use these commands to store updates to models, so if the application cannot connect to the services, the commands will be queued for when the connection comes back.
This has always been a little bit of a sticking point for me with generic interfaces, how do i handle the multitude of possible arguments?
My first thought was to pass the model itself, with a simple string argument with the command type (Delete, Update, etc) however since my models do not have any common base class or interface i'm left with a similar problem.
Am i missing something basic here?
EDIT : Example of my problem was requested.
I have a CommandFactory Interface as such
public interface ICommandFactory
{
string CommandName { get; }
string Description { get; }
ICommand MakeCommand( ..arguments.. )
}
And i have simple models such as (pure example)
public class Model1
{
public string Name {get;set;}
public int Age {get;set;}
}
public class Model2
{
public DateTime Time {get;set;}
public double Price {get;set}
}
If i wanted to create a command that for example updated a model1, i'm left wondering how the Interface's MakeCommand should look, i can't do MakeCommand(string cmdType, Model1 model) because i have multiple different models which share no common baseclass/interface
It looks like you want the individual models to define how they can be updated. In that case, can you not pass a Function/Action from the Model to the MakeCommand?
public class Model
{
public string Name {get;set;}
public int Age {get;set;}
public void UpdateModel() {...}
}
public interface ICommandFactory
{
string CommandName { get; }
string Description { get; }
ICommand MakeCommand(Action<Model>);
ICommand MakeCommandFunc(Func<Model, bool>);
}
public class Command : ICommand
{
Action<Model> _action;
Command(Action<Model> action)
{
_action = action;
}
Execute()
{
_action();
}
}
EDIT:
As requested, use common interface class to model all classes
public interface IModel
{
void UpdateModel();
}
public class Model1 : IModel
{
public string Name {get;set;}
public int Age {get;set;}
// implement updating of the model
public void UpdateModel() {...do model update...}
}
public class Model2 : IModel
{
public DateTime Time {get;set;}
public double Price {get;set}
// 'dummy' implement updating of the model if this model does not supports updating
public void UpdateModel() { // do nothing or throw NotImplementedException(); }
}
public interface ICommandFactory
{
string CommandName { get; }
string Description { get; }
ICommand MakeCommand( IModel model );
}
I suggest you to use command pattern, this pattern use receiver as object which contains arguments, in your receiver you can add list or dictionary of objects.
In this site you can find source code
link : http://www.dofactory.com/net/command-design-pattern
You could also make the ICommandFactory interface generic like so:
public interface ICommandGeneric
{
void execute();
}
public class CommandOnModel1 : ICommandGeneric
{
private Model1 model;
public CommandOnModel1(Model1 model)
{
this.model = model;
}
public void execute()
{
System.Diagnostics.Debug.WriteLine(model.ToString());
}
}
public interface ICommandFactory <in ModelType>
{
string CommandName { get; }
string Description { get; }
ICommandGeneric MakeCommand(ModelType model, string parameter1);
}
public class Model1
{
}
public class Model1CommandFactory : ICommandFactory<Model1>
{
public string CommandName
{
get { return "CommandOnModel1"; }
}
public string Description
{
get { return "I do stuff on Model1"; }
}
public ICommandGeneric MakeCommand(Model1 model, string parameter1)
{
return new CommandOnModel1(model);
}
}
Having said that, I am not entirely sure you should use a factory and maybe not even the command pattern here.
Related
Using the context of Models and View Models from MVVM, how can I deal with this situation?
I have two abstract classes that will be the base of all models and view models in my program; BaseModel and BaseViewModel.
They look like the following.
public abstract class BaseModel {
public string Name { get; set; }
}
public abstract class BaseViewModel {
protected readonly BaseModel baseModel;
public BaseViewModel(BaseModel baseModel) {
this.baseModel = baseModel;
}
public string Name {
get => baseModel.Name;
set {
baseModel.Name = value;
}
}
}
I also have these two classes that will be used with a specific view in my program; UseableModel and UseableViewModel.
They look like the following.
public class UseableModel : BaseModel {
public string NewVar { get; set; }
}
public class UseableViewModel : BaseViewModel {
public UseableViewModel(UseableModel model) : base(model) { }
public string NewVar {
get => baseModel.NewVar;
set {
baseModel.NewVar = value;
}
}
}
The problem is this obviously won't work as UseableViewModel.NewVar tries to make reference to a property that doesn't exist in BaseModel.
What is the best way to allow every view model to keep the behaviour defined in the BaseViewModel but to use its own model that is extended from BaseModel?
Potential solutions
There are several potential solutions such as write a Name property in each view model but that could be a lot of duplication depending on how many view model there were.
You could also define a separate model in the view model like
//...
private readonly UseableModel model;
public UseableViewModel(UseableModel model) : base(model)
{
this.model = model
}
//...
But then there is the problem of data sets being duplicated and wasting space as well as there being inconsistent data in between the two models.
So is there a way to do that avoids the duplication of method definitions and avoids the issue described immediately above?
You could make BaseModel and BaseViewModel implement generics. Something like:
public abstract class BaseModel<TModel>
{
public string Name { get; set; }
}
public abstract class BaseViewModel<TModel> where TModel : BaseModel<TModel>
{
protected readonly TModel baseModel;
public BaseViewModel(TModel baseModel)
{
this.baseModel = baseModel;
}
public string Name
{
get => baseModel.Name;
set => baseModel.Name = value;
}
}
public class UseableModel : BaseModel<UseableModel>
{
public string NewVar { get; set; }
}
public class UseableViewModel : BaseViewModel<UseableModel>
{
public UseableViewModel(UseableModel model) : base(model) { }
public string NewVar
{
get => baseModel.NewVar;
set => baseModel.NewVar = value;
}
}
Im doing an MVC 5 proyect using DI with IoC (Autofac) and the use of Generic Repository for the Data access part.
Now, my controller have an interface as a property injected to it called IProg_II_ModelFactory, this is the concrete class in question:
public class Prog_II_ModelFactory : IProg_II_ModelFactory
{
#region Fields
private readonly IGenericRepository<T> _genericRepository;
#endregion
#region Ctor
public Prog_II_ModelFactory(
IGenericRepository<T> genericRepository
)
{
_genericRepository = genericRepository;
}
#endregion
#region Methods
public Prog_II_Model SetProgIIModelStartUp()
{
var model;
model.FillList = _genericRepository.GettAll();
//Other things to be filled.
return model;
}
}
And my controller is injecting the interface of this class, here is the controller:
public class HomeController : Controller
{
private readonly IProg_II_ModelFactory _prog_II_ModelFactory;
public HomeController(
IProg_II_ModelFactory prog_II_ModelFactory
)
{
_prog_II_ModelFactory = prog_II_ModelFactory;
}
public ActionResult Index()
{
var model = _prog_II_ModelFactory.SetProgIIModelStartUp();
return View(model);
}
}
The problem with this is that Prog_II_ModelFactory must be generic (Prog_II_ModelFactory<T> where T : class)
The problem with this is that, it wont stop there, then it will ask me that the controller should also be generic and on top of that as Im using Autofac, the partial class to for the binding must be generic too and the App_Start itself!.
Is there any way I can use the Generic Interface of My repository without to flow TEntity all the way to App_Start ?
I read that I can use a method? but a lot of people is against this.
Edit:
Maybe instead of the property being Out of T, I have to type it?
for example:
#region Fields
private readonly IGenericRepository<Student> _genericRepository_Student;
private readonly IGenericRepository<Teacher> _genericRepository_Teacher;
#endregion
#region Ctor
public Prog_II_ModelFactory(
IGenericRepository<Student> genericRepository_Student,
IGenericRepository<Teacher> genericRepository_Teacher
)
{
_genericRepository_Student = genericRepository_Student;
_genericRepository_Teacher = genericRepository_Teacher;
}
#endregion
This means I cant do it at runtime, I have to know to which entity at compile time, what if I have 20 tables.
Edit 2:
This is my Model:
namespace Prog_II.Models
{
public class Prog_II_Model
{
#region Fields
public StudentModel Student{ get; set; }
public List<TurnModel> Turns{ get; set; }
public List<CarrerModel> Carrers { get; set; }
public List<StudentModel> Students{ get; set; }
#endregion
#region Ctor
public Prog_II_Model(){}
#endregion
}
public class StudentModel
{
#region Fields
public string Name { get; set; }
public string LastName{ get; set; }
public string NumberId { get; set; }
public string Carrer { get; set; }
public string Turn { get; set; }
#endregion
}
public class TurnModel
{
public string Description{ get; set; }
}
public class CarrerModel
{
public string Description{ get; set; }
}
}
And sure enough I pass a Prog_II_Model in my view:
#using Prog_II.Models
#model Prog_II_Model
public HomeController(Prog_II_ModelRepository modelRepository)...
public class Prog_II_ModelRepository()
{
IGenericRepository<Student> _genericRepository_Student; // get from somewhere
public Prog_II_Model GetModel()
{
var model = new Prog_II_Model();
model.Student = _genericRepository_Student.Get(); // some student
// put the rest of data into your huge all-encompassing model
return model;
}
}
That's just the idea - if you put all your data in a single model object, type-specific repositories are useful inside this single model repo, but it itself has no need to be generic (as opposed to general :)
I think there's something wrong with this One Huge Model approach, but YMMV.
Is your HomeController supposed to handle multiple entity types (Student, Teacher, Janitor, Dog, Cat, ...)? Is your Model flexible enough to handle all and any of them? If yes, use a non-generic repository interface, returning an object or some base entity type. If no, and you have different models per entity type (Dog has Color and Student has Scores), then your domain model asks for controller-per-entity type, inherited, as you said, from a generic controller type.
I don't see any reason for App_Start to be generic.
I'm stuck in my inheritances bloating here:
First let me explain the premise of my problem.
My Model:
public class Person
{
[Key]
public int PersonId { get; set; }
[MaxLength(100)]
public string Name { get; set; }
}
public class SuperHero:Person
{
[MaxLength(100)]
public string SuperHeroName { get; set; }
public virtual ICollection<SuperPower> SuperPowers{ get; set; }
}
Now, I am trying to create my viewModels for my MVC website, I have those base classes that need to be inherited by all other viewmodel displaying/editing a Person/SuperHero:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
public class BaseSuperHeroViewModel : BasePersonViewModel
{
public List<string> SuperPowers{ get; set; }
ctors()
}
Here is where I am stuck, I am trying to define only one ViewModel that could be used regarless of the base class and access property of Person and/or SuperHero (if the Person is a superhero). I've been pulling my hair out but so far only found a solution which i don't like:
Example:
public class SomeViewModel<T> where T : BasePersonViewModel
{
public BasePersonViewModel obj;
public DateTime BirthDate { get; set; }
public SomeViewModel(Person data) //: base(data)
{
if (data is SuperHero)
obj = new BaseSuperHeroViewModel (data);
else
obj = new BasePersonViewModel(data);
}
}
While this would work it's really not sexy to use. And on top of that, I could have another ViewModel that inherit from SomeViewModel as well.
Is there a cleaner way to achieve this?
Edit
My main goal is to be able to able to cast my SomeViewModel depending on the one of the baseclass. Let's say do something like in my Controller:
if myclass is SomeViewModel (of type SuperHero)
Exactly how you do it for Person/SuperHero db retrival/check
var data = context.Person.first(w=> w.Id==1)
if (data is SuperHero)
..
I would like this because I would like to use the same viewmodel let's say to list superhero and person, and just display slightly differently if it's a superhero
Edit 2
I was trying to avoid using the whole Model.Obj to be able to see it directly with the Model... But the more i think about it, the more I think this is not possible really... On top of that I would like to extend some other superHero specific properties in SomeViewModel (only if SomeViewModel is a superhero), that are not declared in the BaseSuperHeroModel one... Let's say in SomeViewModel I want the field 'ComesFromPlanet' only if superhero.
Edit 3
I thought about another way to do it, but it obviously creating various ViewModel.
For the most general case (all fields that are shared for all Person) I would keep my base:
public class BasePersonViewModel
{
public string Name { get; set; }
ctors()
}
I interface specific Person:
public Interface IBaseSuperHero
{
[MaxLength(100)]
public string SuperHeroName { get; set; }
public List<string> SuperPowers{ get; set; }
}
I would keep as well OtherViewModel like this:
public class SomeViewModel:BasePersonViewModel
{
Public datetime Birthdate {get;set;}
}
Then I would create a specific SomeviewModel for other Person inheritant and used interfaces to have old and new properties.
For example:
public class SomeViewModelSuperHero:SomeViewModel, IBaseSuperHero
{
public string OriginalPlanet {get;set;}
}
Is this a clean solution?
Sorry I'm sure I am not clear about this, but I try !
Thanks for your input and time.
I am trying to define only one ViewModel that could be used regarless of the base class and access property of Person and/or SuperHero (if the Person is a superhero)
Assuming you'd return default values for super-hero properties when the model is not a super-hero, you could do something like this:
public class PersonOrSuperHeroViewModel {
private Person person;
private SuperHero superHero;
public PersonOrSuperHeroViewModel(Person personOrSuperHero) {
if (personOrSuperHero is SuperHero) superHero = personOrSuperHero;
person = personOrSuperHero;
}
public IsSuperHero { get { return superHero != null; } }
... // super-hero properties only work when IsSuperHero == true
}
How about something like
public class Person {
public virtual BasePersonViewModel MainViewModel {
get { return new BasePersonViewModel(this);}
}
}
public class SuperHero : Person {
public override BasePersonViewModel MainViewModel {
get { return new BaseSuperHeroViewModel(this);}
}
}
So if all your people classes override the MainViewModel property to return the appropriate view, you don't need
public BasePersonViewModel obj;
public SomeViewModel(Person data) {
if (data is SuperHero)
obj = new BaseSuperHeroViewModel (data);
else
obj = new BasePersonViewModel(data);
}
Because you can have
public BasePersonViewModel obj;
public SomeViewModel(Person data) { obj = data.MainViewModel; }
which will work however many subclasses of person you have.
I have a base class like this:
public class BaseResponse
{
public string ErrorMessage { set;get;}
}
And some child classes which inherit from this:
public class Person:BaseResponse
{
public string FirstNAme { set;get;}
}
public class Phone:BaseResponse
{
public string SerialNumber { set;get;}
}
public class Car :BaseResponse
{
public string Year{ set;get;}
}
Now I want to set the ErrorMessage property of each instance of this class to a different value. Currently this is what I am doing:
public Phone GetPhoneError(Phone objPhone)
{
objPhone.ErrorMessage="Err msg related to Phone";
return objPhone;
}
public Person GetPersonError(Person objPerson )
{
objPerson .ErrorMessage="Err msg related to Person";
return objPerson ;
}
... another similar method for Car also
Is there any way I can make this method a generic format so that I don't need 3 separate methods for setting the error message?
public T GetError<T>(T obj) where T: BaseResponse
{
obj.ErrorMessage= string.Format("Err msg related to {0}", typeof(T).Name);
return obj;
}
I don't know if the error message is this generic thing or something custom. If so, then pass the message as an argument.
Why do you need a method for this? Is it because you have simplified the question?
So in your base class you should create a virtual method called SetError (your GetError but with the correct notation).
public abstract string GetErrorMessage(); //In Base Class so that why each implementation will set the correct error message
Then in your base class - also why do you need to return the same object that you are modifying?
public virtual void SetErrorMessage()
{
this.ErrorMessage = GetErrorMessage();
}
You should be able to have a generic method like so:
public object GetError(BaseResponse response)
{
response.ErrorMessage = "whatever";
return response;
}
Why not make property virtual and no need for set in that case ? :
public class BaseResponse
{
public virtual string ErrorMessage { get;}
}
public class Person:BaseResponse
{
.....
public override string ErrorMessage {get { return "Err msg related to Person";}}
}
public class Phone:BaseResponse
{
......
public override string ErrorMessage {get { return "Err msg related to Phone";}}
}
and so on for others....
I have a customer hierarchy like so:
abstract class Customer {
public virtual string Name { get; set; }
}
class HighValueCustomer : Customer {
public virtual int MaxSpending { get; set; }
}
class SpecialCustomer : Customer {
public virtual string Award { get; set; }
}
When I retrieve a Customer, I would like to show on the web form the properties to edit/modify. Currently, I use if statements to find the child customer type and show the specialized properties. Is there a design pattern (visitor?) or better way so I can avoid the "if" statements in presentation layer? How do you do it?
Further information: This is an asp.net website with nHibernate backend. Each customer type has its own user control on the page that I would like to load automatically given the customer type.
Can you use reflection to get the list of properties specific to an subclass (instance)? (Less error-prone.)
If not, create a (virtual) method which returns the special properties. (More error prone!)
For an example of the latter:
abstract class Customer {
public virtual string Name { get; set; }
public virtual IDictionary<string, object> GetProperties()
{
var ret = new Dictionary<string, object>();
ret["Name"] = Name;
return ret;
}
}
class HighValueCustomer : Customer {
public virtual int MaxSpending { get; set; }
public override IDictionary<string, object> GetProperties()
{
var ret = base.GetProperties();
ret["Max spending"] = MaxSpending;
return ret;
}
}
class SpecialCustomer : Customer {
public virtual string Award { get; set; }
public override IDictionary<string, object> GetProperties()
{
var ret = base.GetProperties();
ret["Award"] = Award;
return ret;
}
}
You probably want to create sections (fieldsets?) on your Web page, anyway, so if would come into play there, making this extra coding kinda annoying and useless.
I think a cleaner organization would be to have a parallel hierarchy of display controls or formats. Maybe use something like the Abstract Factory Pattern to create both the instance of Customer and of CustomerForm at the same time. Display the returned CustomerForm instance, which would know about the extra properties and how to display and edit them.
new:
interface CustomerEdit
{
void Display();
}
edit:
abstract class Customer {
protected CustomerEdit customerEdit; // customers have an object which allows for edit
public virtual string Name { get; set; }
public void Display() { customerEdit.Display(); } // allow the CustomerEdit implementor to display the UI elements
}
// Set customerEdit in constructor, tie with "this"
class HighValueCustomer : Customer {
public virtual int MaxSpending { get; set; }
}
// Set customerEdit in constructor, tie with "this"
class SpecialCustomer : Customer {
public virtual string Award { get; set; }
}
usage:
Customer whichCouldItBe = GetSomeCustomer();
whichCouldItBe.Display(); // shows UI depeneding on the concrete type
Have you tried something like this:
public class Customer<T>
where T : Customer<T>
{
private T subClass;
public IDictionary<string, object> GetProperties()
{
return subClass.GetProperties();
}
}
With a subclass of:
public class FinancialCustomer : Customer<FinancialCustomer>
{
}
This is off the top of my head so might not work. I've seen this type of code in CSLA.NET.
Here's the link to the CSLA.NET class called BusinessBase.cs which has a similar definition to what I've given above.