I have a Viewmodel that have another Viewmodel inside, take a look
[Validator(typeof(ParentValidatorVM))]
public class ParentVM {
public ChildVM { get; set; }
public ParentVM () {
this.ChildVM = new ChildVM ();
}
}
//rulles for validation
internal sealed class ParentValidatorVM : AbstractValidator<ParentVM> {
public ParentValidatorVM() {
//set rules
this.RuleFor(x => x.ChildVM).NotValidate();
//the row above is just an example the method 'NotValidate', I invented
}
}
The ChildVM has the structure with properties
[Validator(typeof(ChildValidatorVM))]
public class ChildVM {
//My properties
}
//rulles for validation
internal sealed class ChildValidatorVM : AbstractValidator<ChildVM> {
public ChildValidatorVM() {
//set rules
}
}
My problem is, when I call ModelState.isValid the rules from the child comes together the rules from the Parent, it is not to happen.
Someone know a way to avoid it?
Related
I have a common class PopupDialog which has properties such as bool IsBackDismissEnabled. This is used to denote whether pressing back button will dismiss the dialog.
I am using Xamarin.CommunityToolkit Popup for showing a popup dialog.
Here's my PopupDialog.cs
public class PopupDialog
{
public bool IsBackDismissEnabled { get; set; }
}
Here's my Dialog Implementation
using Xamarin.CommunityToolkit.UI.Views;
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ForgotPasswordDialog : Popup<PopupDialog>
{
public ForgotPasswordDialog()
{
InitializeComponent();
// I want to access IsBackDismissEnabled here
// something like base.IsBackDismissEnabled = true;
}
}
I want to access PopupDialog's IsBackDismissEnabled from the derived class of Popup<PopupDialog> how can it be done?
In short, I have a class which is specified as a parameter to a generic class. And that generic class is derived in a class from which I want to access properties of previous class that is specified as a parameter to the generic class.
I've never seen anyone attempt to do what you are attempting. I'm not even sure it makes logical sense. Please explain what you are trying to do: Why do you want PopupDialog to be a generic parameter?
Consider making it a parameter on Popup's constructor, and save it in a property or field:
public class Popup
{
public Popup(ISomeInterface myParam)
{
this.MyParam = myParam;
}
public ISomeInterface MyParam;
}
public class ForgotPasswordDialog : Popup
{
public ForgotPasswordDialog() : base(new PopupDialog())
{
}
void SomeMethod()
{
// Access MyParam
... this.MyParam.IsBackDismissEnabled ...
}
}
public interface ISomeInterface
{
bool IsBackDismissEnabled { get; set; }
}
public class PopupDialog : ISomeInterface
{
public bool IsBackDismissEnabled { get; set; }
...
}
/// Usage
var myVariable = new ForgotPasswordDialog();
... myVariable.MyParam.IsBackDismissEnabled ...
To be useful, you'll want to specify an interface or base class that MyParam has. Here I show ISomeInterface. This might instead be some base class of PopupDialog.
Is there a way to get custom attributes which are added along the flow? I'm adding custom attributes to different methods in different classes that are called depending on the flow. I've tried MethodBase.GetCurrentMethod() but this (as it says) only the current invoked method. Using new StackFrame(n) also doesn't work since "n" can frequently change. Googled my problem but didn't find any hints.
public class CustomAttribute1 : Attribute
{
public bool Property { get; }
public CustomAttribute1(bool property) => Property = property;
}
public class CustomAttribute2 : Attribute
{
public string Property { get; }
public CustomAttribute2(string property) => Property = property;
}
public class GeneralService
{
protected void Resolve()
{
// Here I want to access custom attributes combined
}
}
public class SpecifiedService : GeneralService
{
[CustomAttribute1(true)]
public void SendRequest()
{
Resolve();
}
}
public class Worker
{
[CustomAttribute2("init")]
public void Init()
{
var service = new SpecifiedService();
service.SendRequest();
}
}
Firstly, I feel sorry about the title, I do not know how to describe my problem exactly. I hope it will be better explained through the code.
public abstract class AB {
public MyModel Model;
}
public class A : AB {
public A() {
Model = new MyModelA();
}
public void AMethod() {
var model = (MyModelA) model; // I have to do this all place
}
public void AnotherMethod() {
var model = (MyModelA) model; // same here
model.NewInt = 123;
}
}
public abstract class MyModel {
}
public class MyModelA : MyModel {
// new properties
public int NewInt {get;set;}
}
Take a look at the code, in order to use new properties from derived class, I have to do a cast but it is ugly when I have to use it same time all over places.
The method I think is declare another property: public MyModelA _tmp then I cast it in the constructor _tmp = (MyModelA) Model and use it instead of Model.
Are there any other appropriate ways to do this ?
Thanks !
You can make the base class generic:
public abstract class ServiceBase<TModel> where TModel : new() {
protected ServiceBase() { Model = new TModel(); }
public TModel Model { get; private set; }
}
public class AService : ServiceBase<MyModelA> {
...
}
You can maintain your Model reference in the derived class:
public abstract class AB {
public MyModel Model;
}
public class A : AB {
MyModel MyModel;
public A() {
MyModel = new MyModelA();
Model = MyModel;
}
public void AMethod() {
//just use MyModel
}
public void AnotherMethod() {
MyModel.NewInt = 123;
}
}
public abstract class MyModel {
}
public class MyModelA : MyModel {
// new properties
public int NewInt {get;set;}
}
The solution with _tmp rids you of having to write that manual cast all the time, but the problem of a strange object design remains.
I would guess your NewInt is there to perform some sort of functionality that was also present in MyModel (otherwise you'd be better off creating a new class for that to begin with). I'm wondering if you can't encapsulate that functionality in a way that MyModelA does not have to expose anything new. This may mean changing the definition of AB in order to allow for such generalizations.
The answer, I believe, is neither syntactic nor easily found in a OOP pattern without understanding the domain. Maybe you can provide some details on that.
Sorry for the confusing title of the question. I am uncertain about how should I implement ViewModels and Models which derive from a base class.
My ViewModel classes are based on a ViewModelBase, the ViewModelBase holds a ModelBase which serves as a base class for all other models.
Each ViewModel holds a "Model" Property, however, because a Model property was defined by the base ViewModel class as the ModelBase class, I always have to create another property which casts the Model - from ModelBase to the relevant Model class.
My question is - is there not a simpler solution? Is there a design pattern which is relevant for these issues?
Here's a code sample:
public abstract class BasicViewModel : ViewModelBase
{
public BasicViewModel()
{
}
public ModelBase Model { get; set; }
}
public class ModelBase
{
}
public class ContainableViewModel : BasicViewModel
{
public ContainableViewModel(ContainableModel model)
{
this.Model = model;
}
public ContainableModel MyModel { get { return (ContainableModel)Model; } }
public int Children { get { return MyModel.Children; } set { MyModel.Children = value; } }
}
public class ContainableModel : ModelBase
{
public ContainableModel()
{
Children = 2;
}
public int Children { get; set; }
}
As you can see, the "MyModel" property is the one which bugs me.
Thank you very much for your help and time!
If each of your view model contains a Model property, you could use generics:
public abstract class BasicViewModel<TModelType> : ViewModelBase
where TModelType : ModelBase
{
public BasicViewModel(TModelType model)
{
Model = model;
}
public TModelType Model { get; set; }
}
public class ModelBase
{
}
Your containable view model is now defined as follows:
public class ContainableViewModel : BasicViewModel<ContainableModel>
{
public ContainableViewModel(ContainableModel model)
: base(model)
{
}
// you can now omit this method, it is defined on the abstract superclass
//public ContainableModel Model { get { return ()Model; } }
public int Children { get { return MyModel.Children; } set { MyModel.Children = value; } }
}
public class ContainableModel : ModelBase
{
public ContainableModel()
{
Children = 2;
}
public int Children { get; set; }
}
I generally don't use a base class for the different Model types, as there is generally not a one to one correspondance between ViewModel and Model objects. Further, the Model objects generally don't have much in common. This is different from the ViewModel objects, which all tie in via data binding and therefore could benefit from various helper methods that standardize the way you bind to your ViewModel instances.
The 'Model' in Model-View-ViewModel is a layer which provides your business logic and data interaction (everything not related to visualization and interaction with the user.) Your CustomerViewModel for your CustomerWindow might make use of a Customer object from your Model layer, but it very likely has references to other objects from your model, like some sort of Repository. Other Views, like say your MainWindow, might have a MainViewModel that doesn't directly correspond to any Model object, but probably has at least a few dependencies on your Model.
I have a need to create a couple of classes that will serve as base classes for some data functionality I want to implement.
The first, we'll call SessionObjectDataItem looks like this ...
public class ObjectSessionDataItem
{
public int ID { get; set; }
public bool IsDirty { get; set; }
public bool IsNew { get; set; }
public bool IsRemoved { get; set; }
}
And next I want a List called ObjectSessionDataList and this is where I get stuck.
I can create the class OK ...
public class SessionObjectDataList<SessionObjectDataItem> : List<SessionObjectDataItem>
{
}
where I fall down is trying to define properties on the list that access items in it. For example, I want to write...
public List<SessionObjectDataItem> DirtyItems
{
get
{
return this.Where(d => d.IsDirty).ToList();
}
}
but VS refuses to recognise the SessionObjectDataItem property IsDirty inside the List object definition.
What I'm trying to end up with is a case where I might define
public class AssociatedDocument : SessionObjectDataItem
{
...
}
public class DocumentList : SessionObjectDataList
{
}
And then be able to say...
DocumentList list = new DocumentList();
...
foreach(AssociatedDocument doc in list.DirtyItems)
{
...
}
Can I actually do what it is that I'm attempting? Am I just doing it wrong?
Generic constraints will help here; you can write a container-class for which the generic type-parameter is constrained to be SessionObjectDataItem or one of its subtypes. This will allow you to construct a generic class that can hold instances of a specific sub-type of SessionObjectDataItem.
public class SessionObjectDataList<T> : List<T> where T : SessionObjectDataItem
{
public SessionObjectDataList<T> DirtyItems
{
get
{
return this.Where(d => d.IsDirty).ToList();
}
}
}
Usage:
var list = new SessionObjectDataList<AssociatedDocument>();
...
foreach(AssociatedDocument doc in list.DirtyItems)
{
...
}
Try to use the generic version Where<T> of the queryable interface:
public List<SessionObjectDataItem> DirtyItems
{
get
{
return this.AsQueryAble().Where<SessionObjectDataItem>(d => d.IsDirty).ToList();
}
}
Else Where simply assumes d as type Object.