How to avoid having to keep casting the argument? - c#

I am writing a simple MVC pattern. My Views implement a simple interface.
public interface IComponentView
{
void Render(ComponentModel componentModel);
}
Here the ComponentModel is an abstract model class. Controllers are the ones responsible for preparing the new component model and call the view's Render() method while passing the new model. As you can imagine the first thing the view does inside it's own Render() function is to downcast the received parent class ComponentModel to its appropriate child class model so that all the properties and such are available for the view to use for rendering. Here is an example.
public SpecialMenuView : IComponentView
{
...
public void Render(ComponentModel componentModel)
{
SpecialMenuModel model = (SpecialMenuModel)componentModel;
// use model to render stuff
}
...
}
Is there a better way to do this rather than keep down casting for every single UI component I have?

I don't know what you're using this interface for, but if you want to transfer type information, why not generics?
public interface IComponentView<TModel> where TModel : ComponentModel
{
void Render(TModel componentModel);
}
public SpecialMenuView : IComponentView<SpecialMenuModel>
{
...
public void Render(SpecialMenuModel componentModel)
{
// use model to render stuff
}
...
}
You can make that interface contravariant for bonus points.

Not sure of an easy way to do it without generics. You can however make is nicer to follow with some pattern matching, which also takes care of ensuring the cast is fine and the model is ready to work with.
public class SpecialMenuView : IComponentView
{
public void Render(ComponentModel componentModel)
{
if (componentModel is SpecialMenuModel model)
{
// use model to render stuff
model.GetType();
}
}
}

Related

Create mock of class without calling original class constructor

Say i have library with this code (that canot be changed)
namespace Library.Namespace;
public interface ISomething { }
internal class Something : ISomething {
public Something(...) {
...
}
}
public class Anything {
private Something _Something;
public Anything (ISomething something) {
_Something = (Something) something;
...
}
}
and i want to create mock of Anything class:
public MockAnything : Mock<Anything> {
public MockSomething Something { get; }
public MockAnything()
: this(new MockSomething()) {
}
public MockAnything(MockSomething something)
: base(something.Object) {
Something = something;
}
}
public MockSomething : Mock<ISomething> {
}
everythig good so far (aka compiller is happy), but at runtime im getting exception when calling:
var mock = new MockAnything();
var object = mock.Object; // <-- exception here
System.InvalidCastException
Unable to cast object of type 'Castle.Proxies.ISomethingProxy' to type 'Library.Namespace.Something'.
at Library.Namespace.Something..ctor(ISomething something)
at Castle.Proxies.AnythingProxy..ctor(IInterceptor[] , ISomething something)
any idea how to correctly mock class, that uses direct cast in constructor?
When using Moq, the best and easiest way is to create mocks based on interfaces. Unfortunately, you cannot change the library and add an interface there or get rid of the cast (which would be best anyway).
From a design perspective, I'd recommend to create a wrapper around the library code that you cannot change. In addition, you create an interface (let's call it IAnything) that contains the methods that you want to use. Instead of using Anything directly in your code, you'd inject IAnthing into your code. The following code outlines the necessary classes:
public IInterface IAnything
{
// Members of the original Anything class that you want to use in your code
}
public class AnythingWrapper : IAnything
{
private readonly Anything _anything;
public AnythingWrapper(Anything anything)
{
_anything = anything;
}
// IAnything implementation
}
While this might seem like a bit of extra work, it usually is done with some paste-and-copy. In addition, you create a layer of abstraction between your code and the library code. If the library changes in the future, you could be able to apply the changes in your wrapper class without changing the interface as such.
As soon as you have created the interface, you can easily create a mock, e.g.:
var mockAnything = new Mock<IAnything>();

Interface importance in Prism implementation

Is it necessary to implement interface at module level and with viewmodel in prism application?
I am not seeing any interface which could be used with multiple class.
No, view models in prism do not need to implement any interface. Not even INotifyPropertyChanged, if you don't have any data that changes from the logic-side and not from the view.
In older versions, there was IView which the views had to implement to use the ViewModelLocator, but that doesn't exist anymore.
Module definitions need to implement IModule.
EDIT after comments:
You want to create an interface for a single class if you want to be able to replace it with another class, either in production or in test.
That being said, you don't create an interface for a class, normally, but the other way round. The interface comes first and specifies what the consumer wants to do with the implementation and then one or more classes provide the implementation for one or more interfaces each.
Example:
Given the class
internal class InventoryManager
{
public IEnumerable<string> ListItems() { ... }
public void AddItem( string item ) { ... }
public void RemoveItem( string item ) { ... }
}
you don't create this interface:
public interface IInventoryManager
{
IEnumerable<string> ListItems();
void AddItem( string item );
void RemoveItem( string item );
}
but rather these two:
public interface IItemList
{
IEnumerable<string> ListItems();
}
public interface IItemStorage
{
void AddItem( string item );
void RemoveItem( string item );
}
because your interface's consumers will probably either want to look what's in the inventory or change it. And you want the option to implement a read-only inventory differently than a writeable one.

Generic DAL / BLL Classes

I'm currently building the Data Access Layer and Business Logic Layer classes for our new application, and I have a question (obviously). First, here are some details that may help:
Using Entity Framework 5 for Model classes and data access
Each "layer" is separated in different class libraries and namespaces (i.e App.Model, App.DAL, App.BLL)
Starting with the DAL - I decided to write a base class for all DAL classes to inherit.
public abstract class DALBase<T> : IDisposable
{
protected AppEntities context;
protected DbSet set;
public DALBase()
{
context = new OECCORPEntities();
set = context.Set(typeof(T));
}
protected virtual void Save()
{
context.SaveChanges();
}
public virtual void Add(T model)
{
set.Add(model);
Save();
}
public virtual T Get(int id)
{
return (T)set.Find(id);
}
public virtual List<T> GetAll()
{
return set.OfType<T>().ToList();
}
public virtual void Delete(int id)
{
T obj = Get(id);
set.Remove(obj);
Save();
}
public virtual void Update()
{
Save();
}
public void Dispose()
{
context.Dispose();
}
}
As you will see, the base class implements a generic type which should be the type of the model the DAL class is responsible for working with. Using the generic type, in the constructor it creates a DbSet using the type of the generic argument - which is used in the predefined CRUD-like virtual functions below (add, get, etc).
And then I got the idea - wait a minute... since it's generic, I really don't have to implement DAL classes for every single model. I can just write something like this:
public class GenericDAL<T> : DALBase<T>
{
public GenericDAL() : base() {}
}
... that I can use for any of the models. OK, so on to the Business Logic Layer. I created a base class for BLL as well:
public abstract class BLLBase<T>
{
protected GenericDAL<T> dal;
public BLLBase()
{
dal = new GenericDAL<T>();
}
public virtual void Add(T model)
{
dal.Add(model);
}
public virtual T Get(int id)
{
return dal.Get(id);
}
public virtual List<T> GetAll()
{
return dal.GetAll();
}
public virtual void Delete(int id)
{
dal.Delete(id);
}
public virtual void Update()
{
dal.Update();
}
}
... which uses the GenericDAL to do its work. So in a simular fashion, I just wrote a GenericBLL class that looks like this:
public class GenericBLL<T> : BLLBase<T>
{
public GenericBLL() : base() { }
}
And to test it, a simple console application:
class Program
{
static void Main(string[] args)
{
GenericBLL<ADMIN> bll = new GenericBLL<ADMIN>();
List<ADMIN> admins = bll.GetAll();
}
}
... where "ADMIN" is the model type. Works like a charm.
The idea behind this was to avoid having to write DAL / BLL classes for every single model, unless it needed extra functionality. Can someone tell me why I WOULDN'T want to do it this way? I think the generic DAL / BLL classes would get the job done and also save development time.
Thank you for your time.
Well, one drawback is that if you decide to add some business rules later on you would have to switch the type from GenericBLL[Whatever] to WhateverBLL.
An obvious solution to this is to create a class that inherits from GenericBLL[Whatever]. Like:
public class WhateverBLL : GenericBLL<Whatever>
and use this class instead.
Right now, your BLL isn't particularly adding value. Every call is simply a pass-through to another layer. Maybe it's the simplicity of your application (and thank your lucky stars that you are so lucky), or maybe you have what I would classify as the actual business logic living elsewhere.
Business logic to me is everything that is done up to the point of persisting data, everything that is done after retrieving data, and things like that. The decisions, the forks in the road, the actions that are taken. Actually saving and retrieving data is typical extremely trivial by comparison.
So as I look at your generic DAL base class, I think it's a fine start. I would probably extract an interface from it so I could replace it when testing. For now, your class that inherits the base isn't adding any value. Do not create layers and classes simply for the sake of it, be sure it adds value and makes your life easier in some way.
As I look at your generic BLL class, I think you probably have your real business logic tucked away in the codebehind on some form, or inside a class file in a console app. While it's certainly possible that there could be generically applicable functionality that only varies on the type, I don't think one class is where you want to be. My suggestion here is to reconsider what you think is your actual business logic. A simple pass-through layer to the DAL probably isn't it.

Generics and inheritance... Getting around having to specify the <T> type?

Well, I've had to rewrite this as I've been down voted five times for giving too much detail... Go figure!
class BaseModel
{
public T[] Get<T>()
{
// return array of T's
}
public T Find<T>(object param)
{
// return T based on param
}
public T New<T>()
{
// return a new instance of T
}
}
class BaseRow
{
private BaseModel _model;
public BaseRow(SqlDataReader rdr, BaseModel model)
{
// populate properties of inheriting type using rdr column values
}
public void Save()
{
// calls _model.Save(this);
}
}
I currently have a number of classes that inherit the BaseModel class. Each of the methods exposed by BaseModel will return an instance, or an array of instances of a type that inherits the BaseRow class.
At the moment, when calling the exposed methods on the BaseModel via an inheriting class, i.e.
using(DeviceModel model = new DeviceModel())
{
DeviceRow row = model.Find<DeviceRow>(1);
DeviceRow[] rows = model.Get<DeviceRow>();
DeviceRow newRow = model.New<DeviceRow>();
}
I have to specify the type (a class that inherits the BaseRow class), as the methods in BaseModel/BaseRow do not know/care what type they are, other than they inherit from BaseRow.
What I would like to do is find a way to remove the need to specify the without having to replicate code in every class that inherits BaseModel, i.e.
class DeviceModel : BaseModel
{
public DeviceRow Find(object param)
{
return this.Find<DeviceRow>(param);
}
}
Note: Unfortunately I am unable to implement or use any third party solutions. That said, I have tried using Castle Active Record/nHibernate and to be honest, they are very big and heavy for what should be a very simple system.
Hopefully I haven't provided "too much" detail. If I have, please let me know.
Thanks
If I were you, I'd suggest making BaseModel a generic class. In a situation of "can't win either way", the code you've removed to make others happy might have told me more about what you're doing (not a criticism by any stretch - I appreciate your position).
class BaseModel<T>
{
public virtual T[] Get()
{
// return array of T's
}
public virtual T Find(object param)
{
// return T based on param
}
public virtual T New()
{
// return a new instance of T
}
}
That's your base, and then you have inheritors like:
class DeviceModel : BaseModel<Device>
{
public override Device New()
{
return new Device();
}
}
Now, any generic operations you define in DeviceModel will default to returning or using strongly typed Device. Notice the virtual methods in the BaseModel class. In the base class methods, you might provide some basic operations predicated upon using T's or something. In sub-classes, you can define more specific, strongly typed behavior.
I'd also comment that you might want to pull back a little and consider the relationship of BaseModel and BaseRow. It appears that you're defining a parallel inheritance hierarchy, which can tend to be a code smell (this is where more of your code might have come in handy -- I could be wrong about how you're using this). If your ongoing development prospects are that you're going to need to add a FooRow every time you add a FooModel, that's often a bad sign.

Creating a Generic Save() Method for Models

I have a fairly simple system, and for the purposes of this question there are essentially three parts: Models, Repositories, Application Code.
At the core are the models. Let's use a simple contrived example:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In that same project is a generic repository interface. At its simplest:
public interface IRepository<T>
{
T Save(T model);
}
Implementations of that interface are in a separate project and injected with StructureMap. For simplicity:
public class PersonRepository : IRepository<Person>
{
public Person Save(Person model)
{
throw new NotImplementedException("I got to the save method!");
// In the repository methods I would interact with the database, or
// potentially with some other service for data persistence. For
// now I'm just using LINQ to SQL to a single database, but in the
// future there will be more databases, external services, etc. all
// abstracted behind here.
}
}
So, in application code, if I wanted to save a model I would do this:
var rep = IoCFactory.Current.Container.GetInstance<IRepository<Person>>();
myPerson = rep.Save(myPerson);
Simple enough, but it feels like it could be automated a lot. That pattern holds throughout the application code, so what I'm looking to do is create a single generic Save() on all models which would just be a shorthand call to the above application code. That way one would need only call:
myPerson.Save();
But I can't seem to figure out a way to do it. Maybe it's deceptively simple and I'm just not looking at it from the correct angle. At first I tried creating an empty ISaveableModel<T> interface and intended to have each "save-able" model implement it, then for the single generic Save() method I would have an extension on the interface:
public static void Save<T>(this ISaveableModel<T> model)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
model = rep.Save(model);
}
But it tells me that rep.Save(model) has invalid arguments. It seems that it's not wiring up the type inference as I'd hoped it would. I tried a similar approach with a BaseModel<T> class from which models would inherit:
public class BaseModel<T>
{
public void Save()
{
this = IoCFactory.Current.Container.GetInstance<IRepository<T>>().Save(this);
}
}
But the compiler error is the same. Is there a way to achieve what I'm trying to achieve? I'm very flexible on the design, so if I'm going about something all wrong on an architectural level then I have room to step back and change the big picture.
Would a generic extension method solve it?
public static T Save<T>(this T current)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
rep.Save(current);
}
You can then constrain it to your ISaveableModel<T> interface. Return type above not implemented, but you can put it to a boolean or status flag, whatever.
In both approaches, the parameter to the Save() function is not of type T. In the first one, it is ISaveableModel<T>, and in the second, it is BaseModel<T>. Since the repository is a generic based on T, Save method will expect a variable of type T. You can add a simple cast to T before you call Save to fix it.
Alternatively, your IRepostory<T> can be changed to
public interface IRepository<T>
{
T Save(ISaveableModel<T> model);
}
which makes more sense.

Categories

Resources