Possible bad practice in Web API ViewModel pattern? - c#

I'm currently implementing ViewModels within my WebApi by injecting a Model object into the constructor of my 'ViewModelProduct' Object, as shown:
public class ViewModelProduct
{
private IProduct _product;
private int _ID;
private string _name;
public ViewModelProduct(IProduct product)
{
_product = product;
ID = _product.ID;
Name = _product.Name;
}
public int ID
{
set { _ID = _product.ID; }
get { return _ID; }
}
public string Name
{
set { _name = value; }
get { return _name;}
}
public string Description
{
set { _product.Description = value; }
get { return _product.Description; }
}
Within the Controller - in my case, the 'ProductController' I want to create an instance of the 'ViewModelProduct'. I want to reduce close coupling where ever possible.
I inject an 'IFacade' object into the constructor of my controller through the use of Unity from a BootStrapper class.
The real question here is I currently have a static method simply returning a new instance of the 'ViewModelProduct' object which I send the Model to to set within its constructor, as shown. Is this bad practice? I can't think how I could create an instance with Unity as I dont know what the model will be before runtime
public List<ViewModelProduct> GetProducts()
{
var V2Ops = _facade.GetOperatorV2();
var productList = V2Ops.GetProducts();
List<ViewModelProduct> listObjects = new List<ViewModelProduct>();
foreach (var product in productList)
{
//*****Setting a new instance from a static method.*****
var viewModel = CreateNewViewModelV2.CreateViewModel(product);
listObjects.Add(viewModel);
}
return listObjects;
}
Static Class returning a new 'ViewModelProduct' instance:
public static ViewModelProduct CreateViewModel(IProduct passedProductModel)
{
return new ViewModelProduct(passedProductModel);
}

It's not bad practice, I actually do it all the time but as an extension method (for IProduct). However, in this particular case, do you really need a factory method? Just doing a new ViewModelProduct(product) should be enough.
Your other option though is not quite good. It's a view model, a DTO for an IProduct, using a DI Container is way overkill and has no benefits. Btw, I don't think the viewmodel needs to be abstracted. As data structure it has no real behaviour (at most some helpers), it's not like you'll have multiple variations of it.

Another way I have gone about this, is as follows:
public static IViewModelProduct CreateViewModel(IProduct passedProductModel)
{
var viewModelContainer = new UnityContainer();
viewModelContainer.RegisterType<IViewModelProduct, ViewModelProduct>(new InjectionConstructor(passedProductModel));
var newViewModelObject = viewModelContainer.Resolve<IViewModelProduct>();
return newViewModelObject;
}
Simply using unity to construct an object from the interface base class. Whilst registering the type, the passed IProduct object has been set to the constructor of the new ViewModelProduct Instance.

Related

Passing a property by reference into a method (same name, different classes)

public class Address
{...}
public class Object1
{
public Address Address {get;set;}
}
public class Object2
{
public Address Address {get;set;}
}
public UpdateAddress(Address address)
{
address = new Address();
}
//calling
var obj1 = new Object1();
UpdateAddress(obj1.Address);
//obj1.Address IS NULL
I cannot have my 2 classes inherit from a baseclass that has Address property (long story)
I was under the impression that when passing objects into methods they are by reference and my obj1.Address will have a new one and not be null if i am passing that property into a method.
If my assumption is wrong and it seems to be about object not being passed by reference in this instance.
How can i have a generic method that I can update a property that is the same across all my objects (I know I can return a new address object but I prefer to be passed in instead of returning)
Can this also be done by passing T<>?
UPDATE - Actual Code
Calling the methods
bool isVendorIdFromModel = UpdateVendor(entity.ExpenseVendor, entity.ExpenseVendorId, model, isNew, context);
if (isVendorIdFromModel)
{
entity.ExpenseVendorId = model.VendorId;
}
private static bool UpdateVendor(ExpenseVendor vendor, int? entityVendorId, ExpenseBaseModel model, bool isNew, ELMSContext context)
{
if (model.VendorId.HasValue)
{
if (entityVendorId != model.VendorId)
{
return true;
}
UpdateVendorInfo(model, vendor);
}
else
{
if (isNew && !string.IsNullOrEmpty(model.VendorName))
{
vendor = new ExpenseVendor
{
...
};
context.ExpenseVendors.Add(vendor);
}
if (vendor != null)
{
UpdateVendorInfo(model, vendor);
}
}
return false;
}
private static void UpdateVendorInfo(ExpenseBaseModel model, ExpenseVendor vendor)
{
vendor.Name = model.VendorName;
vendor.Address1 = model.Address1;
vendor.Address2 = model.Address2;
vendor.City = model.City;
vendor.PostalCode = model.PostalCode?.Replace(" ", string.Empty);
vendor.ProvinceId = model.ProvinceId;
}
Usual options:
shared base class (if you can change code and class hierarchy)
shared interface (if you can can change code, but no class hierarchy)
pass lambdas for getter/setter
use reflection and set by name
Since it sounds like you can't change the source lambda option may be the easiest. Following is option to "set" (when you replace whole object):
public void UpdateAddress(Action<Address> addressSetter)
{
addressSetter(new Address());
}
//calling
var obj1 = new Object1();
UpdateAddress(address => obj1.Address = address);
If you need to set properties of such object instead of replacing - pass get delegate:
public void UpdateAddress(Func<Address> addressGetter)
{
addressGetter().Street = "Dark alley";
}
UpdateAddress(address => obj1.Address);
Or use both. You can even combine them into helper class so it look close to properties (check out adapter pattern.
Note: generics not going to help you unless you can add common interface (but in that case you probably don't need generics at all).
If UpdateAddress only returns an address then change it to:
public Address UpdateAddress()
{
// set up address
return address;
}
var obj1 = new Object1();
obj1.Address = UpdateAddress();
Passing by reference and manipulating the contents of a parameter is a code smell. Write methods that return values and set the property that way.

Is there anyway to reconstruct an object inside itself?

I have a simple class that is intended for options of an winforms application. There should be a method that reset options to their default values. I know I can add a separate method to take care of this, but the code will be huge (If I add more options to the class) :
public SensorOptions()
{
ShowLabelMax = ShowLabelMin = ShowLabelAvr = ShowReceivedTextBox = true;
ChartMaxValue = 140;
ChartMinValue = -40;
ShowChartMinValue = ShowChartMaxValue = ShowChartAvrValue = ShowChartAvrLine = true;
LogFolder = Environment.SpecialFolder.MyDocuments.ToString();
LoggingEnabled = true;
}
public void ResetOptions()
{
this = new SensorOptions(); //can not do. 'this' is read-only
}
I mean I can copy/paste the code from constructor into ResetOptions() method. But is there any smarter ways to achieve this?
You cannot assign this because you may have references to this instance of your class in your program. If you could re-construct the object by re-assigning this, it would mean that all references to the old instance of the class become invalid.
No matter how many options you have in your class, you initialize each of them one or the other way (because you mention default value in your question - so you need to assign that default value somewhere at least once, probably in the constructor). Therefore, the solution to your problem is simple - move all initializers to the separate method and call it in the constructor, and then also call it every time you need to reset your options to their default values.
If any of your options are not assigned a default value explicitly, and use system default and you don't want to write option=default(optionType) for each option, you can use reflection to enumerate all fields/properties in that class and assign default values to them, like this:
public static object GetDefault(Type type)
{
if(type.IsValueType) return Activator.CreateInstance(type);
return null;
}
foreach(var field in this.GetType().GetFields())
field.SetValue(this, GetDefault(field.FieldType));
foreach(var prop in this.GetType().GetProperties())
prop.SetValue(this, GetDefault(prop.PropertyType));
Move all of the code from the constructor into the ResetOptions method, then in your constructor call the ResetOptions method. Your initialisiation code is only in one place then.
You have very simple architecture for your situation. In my opinion it would be better to apply a trick for this:
you have class for holding all your options (pseudo code):
class AllOptionsBackstage
{
public bool ShowLabelMax { get; set; }
public bool ShowLabelMin { get; set; }
public bool ShowLabelAvr { get; set; }
public AllOptionsBackstage()
{
// apply default values here
}
}
.....
class MyOptions
{
private AllOptionsBackstage _options;
public MyOptions()
{
Reset();
}
public bool ShowLabelMax
{
get{ return _options.ShowLabelMax; }
set{ _options.ShowLabelMax = value; }
}
public bool ShowLabelMin
{
get{return _options.ShowLabelMin;}
set{_options.ShowLabelMin=value; }
}
public bool ShowLabelAvr
{
get{ return _options.ShowLabelAvr;}
set{ _options.ShowLabelAvr = value; }
}
public void Reset()
{
_options = new AllOptionsBackstage(); // will reset all your options to default
}
}

How to add a class property to a list of instances

I'm newbie in C#. Perhaps this is too simply to resolve but I'm really away of the solution.
I have this class:
public class TestSetups : TabelaCtset
{
public IList<TabelaCtsca> ValSetup { get { return m_valsetup; } }
private static List<TabelaCtsca> m_valsetup;
/// Constructor
public TestSetups(IDefinitionList dlist)
: base(dlist)
{
m_valsetup = new List<TabelaCtsca>();
}
}
I have another class called TestCase
public class TestCase : TabelaCttes
{
public IList<TestSetups> Setups { get { return m_setups; } }
private List<TestSetups> m_setups;
...
testcase.m_setups = new List<TestSetups>();
defs = gdl.GetDefinitions(testcase);
while (defs.MoveNext())
{
TestSetups testsetup = new TestSetups(defs);
IDefinitionList valsetup = gdl.GetDefinitions(testsetup);
{
TabelaCtsca ctsca = new TabelaCtsca(valsetup);
testsetup.ValSetup.Add(ctsca);
}
testcase.Setups.Add(testsetup);
}
return testcase;
...
}
I want to put all ctsca values in a ValSetup list. All works fine, except this line testcase.Setups.Add(testsetup);: I have the the properties of TestSetups class but my ValSetup property is always empty, when my while goes to another iteration.
Sorry for this weird explanation. I'm able to explain in more detail.
Update: In this situation, I store in each TestSetup just the last ValSetup value and not all the ValSetup of each TestSetup.
You've made m_valsetup a static property, but you're re-initializing every time you create a new instance of TestSetups. If you want it to be a shared list across all instances of TestSetups, then you could use a property initializer like this:
private static List<TabelaCtsca> m_valsetup = new List<TabelaCtsca>();
And remove the initialization of it in the constructor.
If you didn't intend for the list to be shared, then just remove the static keyword from its definition.

Implement a dictionary of classes for a pseudo class factory

I´m trying to buld a class factory like that:
public class Toyota() {};
public class Bmw() {};
public class Mercedes() {};
public class BrandFactory
{
private Dictionary<string, object> _Brands = new Dictionary<string, object> {
{"Toyota", Toyota},
{"Bmw", Bmw},
{"Mercedes", Mercedes}
}
public object GetBrand(string brandName)
{
return = BusinessManagers[brandName].Invoke;
}
}
This is the idea, but it´s not working - I can´t even compile the above code as the Dictionary cannot associate an 'object' with the function. I tried Func<> as well, but in that case it requires a previous type.
So, here are my questions:
Is that a correct way to implement this 'pseudo factory' ? The code came from the example at example code
If so, what needs to be fixed in the above code ?
The reason I´m asking that is because I need to create a new object based on a string that is received from a cliente application using Ajax. Like:
AjaxCall -> String Containing Object Name -> Object Inoke -> Method Call -> Send result back to client
The Method Call is a standard for all implementation of Brand.
Please can someone help me with that ?
Thanks.
You have a several options here. If you end up using a Dictionary, I recommend making it case-insensitive and taking care to avoid KeyNotFoundExceptions.
public class CaseInsensitiveStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
return string.Compare(x, y, ignoreCase: true);
}
}
The first option is to use Dictionary<string, Func<object>>.
private IDictionary<string, Func<object>> _Brands
= new Dictionary<string, Func<object>> (new CaseInsensitiveStringComparer())
{
{"Toyota", () => new Toyota() },
{"BMW", () => new Bmw() },
{"Mercedes", () => Mercedes() }
};
public object GetBrand(string brandName)
{
Func<object> func;
return _Brands.TryGetValue(brandName, out func)
? func() // invoking the delegate creates the instance of the brand object
: null; // brandName was not in the dictionary
}
Second option is to use Activator. You can use a Dictionary<string,Type>, but it may not be necessary if your type name matches the string (see notes below).
public object GetBrand(string brandName)
{
Type type;
return _Brands.TryGetValue(brandName, out type)
? Activator.CreateInstance(type) // activator invokes a parameterless constructor
: null; // brandName was not in the dictionary
}
// vs.
return Activator.CreateInstance(null, brandName).Unwrap();
// Case sensitivity would be an issue here.
// Security could be an issue here.
// Creating objects based directly off of user input means any class
// from any referenced assembly could be created if a hacker can learn
// out the namespaces and class names.
Third option is to use an IoC container to do the resolution. This gives you some flexibility with lifetime management.
The second approach currently assumes a parameterless constructor, wherease the first and third would allow for disparate constructor signatures.
In all cases, the result is simply object, which gives this approach limited utility. If all of these "brand" classes could share a common interface, then you could use IBrand or whatever in your Dictionary and as the return type.
I'm checking for bad data (values not in the Dictionary) and returning null; you could choose to throw an Exception if that makes more sense for your use case.*
You do not need a Dictionary at all:
public class DynamicFactory<T>
{
public static T Create(string className)
{
Type t = typeof(T);
return (T)Activator.CreateInstance(
t.Assembly.FullName,
t.Namespace + "." + className
).Unwrap();
}
}
namespace Brands
{
public class CarBrand { }
// The brands should be in the same namespace and assembly with CarBrand
// and should inherit from CarBrand
public class Toyota : CarBrand { };
public class Bmw : CarBrand { };
public class Mercedes : CarBrand { };
public class Titanic { } // this one is not CarBrand
class BrandFactory: DynamicFactory<CarBrand> { }
// Below are unit tests using NUnit
namespace BrandFactorySpecification
{
static class Create
{
[TestCase("Toyota", Result = typeof(Toyota))]
[TestCase("Bmw", Result = typeof(Bmw))]
[TestCase("Mercedes", Result = typeof(Mercedes))]
[TestCase("Titanic", ExpectedException = typeof(InvalidCastException))]
[TestCase("unknown", ExpectedException = typeof(TypeLoadException))]
[TestCase("String", ExpectedException = typeof(TypeLoadException))]
[TestCase("System.String", ExpectedException = typeof(TypeLoadException))]
[TestCase("ACarBrandFromAnotherNamespace",
ExpectedException = typeof(TypeLoadException))]
[TestCase("AnotherNamespace.ACarBrandFromAnotherNamespace",
ExpectedException = typeof(TypeLoadException))]
//
public static Type ShouldReturnCorrectType(string brandName)
{
return BrandFactory.Create(brandName).GetType();
}
[Test]
public static void ForTitanic()
{
DynamicFactory<Titanic>.Create("Titanic")
.ShouldBeType(typeof(Titanic));
}
}
namespace AnotherNamespace
{
public class ACarBrandFromAnotherNamespace : CarBrand { };
}
}
}
Update: the code was improved in the following ways:
The security problem, mentioned in the comments was fixed
flexibility improved
A new generic class DynamicFactory<T> now can be reused elsewhere
Brands can be located in other namespace and assembly then BrandFactory
Unit tests were added to serve as examples of usage and specification (using NUnit required for them)
That's not at all how a factory works. First of all you need a superclass that can be the parent of your car models:
public class CarModel() {};
public class Toyota() : CarModel {};
public class Bmw() : CarModel {};
public class Mercedes() : CarModel {};
Now you can create a factory that returns the correct model:
public class BrandFactory
{
public T GetBrand<T>() where T : CarModel
{
return new T();
}
}
Now when you want to create a object its is simple:
var factory = new BrandFactory();
var bmw = factory.GetBrand<Bmw>();

method returning same object which was passed as parameter

Is it acceptable practice to pass an object into a method, then return the same object rather than creating a new object inside of the method itself?
As an example: if have an entity class as follows:
class UserDetails {
int UserID { get; set; }
string UserName { get; set; }
string UserAge { get; set; }
}
And then I pass an instance of this class to a method, as follows:
UserDetails UserInfo = new UserDetails();
UserInfo = Get_Details(UserInfo);
Is it reasonable for the method to do the following?
public UserDetails Get_Details(UserDetails user) {
// SQL Operations...
user.age = 32;
return user;
}
IMO, there is no need to return the object. Since it is passed to the method by reference, the caller already has a reference to the same object (with the updated values after the method completes).
On the other hand, what can be useful in some situations is a fluent-interface, where instance-methods of a class return the instance again, e.g:
class X
{
public X DoThis(int number)
{
// do something
return this;
}
public X DoThat(string name)
{
// do something else
return this;
}
}
This allows to write very readable code, such as:
var x = new X().DoThis(23).DoThat("asdf");
This can be useful with the builder pattern (when you want to build a complex object step by step).
As a very bad example:
class FooBuilder {
FooBuilder WithAge(int age);
FooBuilder WithUrl(Url url);
Foo ToFoo();
}
new FooBuilder().WithAge(12).WithUrl(new Url("http://www.happybirthday.com/").ToFoo();
In your particular case, I'd prefer to initialize everything in one go with the initializer syntax.
new User { Age = 45, UserName = "Bob", Id = 101 };
There is nothing horribly wrong with this but a couple of observations;
You are setting details inside of a method called get perhaps load is more appropriate.
If you are only passing in UserDetails because you want the id for your then the parameter should just be id instead. This keeps the interface cohesive.
It is generally considered bad form to modify a parameter object within a method, i.e., mutation principle.
Doing it like that is rather pointless, as the assignment that you do doesn't change anything.
Calling it like this:
UserInfo = Get_Details(UserInfo);
gives the same result as calling it and ignoring the return value:
Get_Details(UserInfo);
Returning the reference may only be confusing, leading someone to believe that the method returns a new instance, as that would be the only logical reason to return a reference.
It would make more sense to have that method in the class, so that you call it as:
UserInfo.Get_Details();
If your method is supposed to initialise the object, you would rather put the code it the constructor than calling it after creating the instance:
class UserDetails {
int UserID { get; set; }
string UserName { get; set; }
string UserAge { get; set; }
public UserDetails() {
Get_Details(this);
}
}
Then you just create the instance, and the constructor loads the data:
UserDetails UserInfo = new UserDetails();
This is a possible approach and when you have only ONE item to work one, the best, too. You might also consider to use ref, which creates a reference to the passed parameter
public void Get_Details(ref UserDetails user)
{
// SQL Operations. . .
user.age= 32;
}
this way, you don't pass a copy, but reference the object you passed in. But this can become quite obscure and is unnecessary in your case. See here for an insight.
You can fill your entity in its constructor method or another method inside entity class. It will be ready to use when created.
public class SomeClass
{
public string Field_1;
public int Field_2;
public SomeClass(int ID)
{
// Sql operations by ID or another value
// set fields
}
public AnotherMethod(int ID)
{
// Sql operations by ID or another value
// set fields
}
}
You might do well to look up the concepts of the Repository Pattern and OOD. In general, I prefer projections or fully loaded entities.
public UserDetailsProjection GetDetailsByUserId(Guid userID)
{
// Code goes here
return user;
}
Note: ref is not required, because all objects are passed by reference.

Categories