I've been reading a few articles the past few days on inheriting classes and creating base classes, which i often do in tools I've written. However I specifically was looking into ways to reduce the redundant code often written in my classes which contain INotifyPropertyChange. Normally my classes look something like this, inheriting the base class of NotifyBase. However I've seen here a there in various scripts people moving some of the Get and Set code into the base class. I wanted to know what things to look out for when doing this? is this bad practice or good practice? Does the example I provided written correctly to do so?
One benefit being the Get and Set are much simpler in the classes which inherit NotifyBase in the new setup.
Current Setup Example
FileItem Class
using System.IO;
namespace WpfApplication1
{
public class FileItem : NotifyBase
{
private string _fullPath;
public string FullPath
{
get { return this._fullPath; }
set
{
this._fullPath = value;
this.NotifyPropertyChanged("FullPath");
}
}
}
}
Base Class 'NotifyBase'
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApplication1
{
public class NotifyBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Possible New Setup
FileItem Class
using System.IO;
namespace WpfApplication1
{
public class FileItem : NotifyBase
{
public string FullPath
{
get { return Get<string>(); }
set { Set(value); }
}
}
}
Base Class 'NotifyBase'
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Varo.Helper
{
public class NotifyBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
private readonly Dictionary<string, object> _propertyValues;
protected NotifyBase()
{
_propertyValues = new Dictionary<string, object>();
}
protected void Set<T>(T value, [CallerMemberName] string name = "")
{
if (_propertyValues.ContainsKey(name))
{
_propertyValues[name] = value;
NotifyPropertyChanged(name);
}
else
{
_propertyValues.Add(name, value);
NotifyPropertyChanged(name);
}
}
protected T Get<T>([CallerMemberName] string name = "")
{
if (_propertyValues.ContainsKey(name))
{
return (T)_propertyValues[name];
}
return default(T);
}
}
}
Check the PropertyChanged.Fody NuGet
Weaves .NET assembly at compile time so properties declared as
public int Property { get; set; }
Gets compiled as
private int property;
public int Property
{
get
{
return property;
}
set
{
if(property != value)
{
property = value;
if (this.PropertyChanged!= null) PropertyChanged(this, new PropertyChangedEventArgs("Property");
}
}
}
Related
How do I raise PropertyChanged for SomeProperty in class B?
This example does not compile since PropertyChanged is not accessible this way...
public class A : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}
public class B : A
{
private object _someProperty;
public object SomeProperty
{
get => _someProperty;
set
{
_someProperty = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SomeProperty)))
}
}
}
Solution 1:
You can use this RaisePropertyChangedExtension:
public static class RaisePropertyChangedExtension
{
public static void RaisePropertyChanged(this INotifyPropertyChanged #this, [CallerMemberName] string propertyName = null)
{
var declaringType = #this.GetType().GetEvent(nameof(INotifyPropertyChanged.PropertyChanged)).DeclaringType;
var propertyChangedFieldInfo = declaringType.GetField(nameof(INotifyPropertyChanged.PropertyChanged), BindingFlags.Instance | BindingFlags.NonPublic);
var propertyChangedEventHandler = propertyChangedFieldInfo.GetValue(#this) as PropertyChangedEventHandler;
propertyChangedEventHandler?.Invoke(#this, new PropertyChangedEventArgs(propertyName));
}
}
Like this:
public class B : A
{
private object _someProperty;
public object SomeProperty
{
get => _someProperty;
set
{
_someProperty = value;
this.RaisePropertyChanged();
}
}
}
In my opinion this is the best solution I know so far.
Disadvantage is that you're able to raise PropertyChanged from another class like this:
public class C
{
public C(B b)
{
b.RaisePropertyChanged(nameof(b.SomeProperty));
}
}
It's not good practise to raise PropertyChanged from other classes this way, so i'm not concerned by this disadvantage.
This solution is inspired by Thomas Levesque's answer here: Simple small INotifyPropertyChanged implementation
Solution 2:
You can create a protected RaisePropertyChanged in the base class A:
public class A : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
And call the method in the derived class B:
public class B : A
{
private object _someProperty;
public object SomeProperty
{
get => _someProperty;
set
{
_someProperty = value;
RaisePropertyChanged();
}
}
}
Disadvantage is that you have to implement the RaisePropertyChanged method for each new base class you're creating on the opposite you avoid the disadvantage that Solution 1 had.
To explain a little more, I have a Main Form which contains a large list of jobs.
Every item in the list is a instance of my class called Jobs.
When an item is clicked, another Form is opening, in which user can edit information of selected job. I pass a job object from Main Form to details Form and edit it through TextBoxes, ComboBoxes and so on.
Now I need to detect which properties of jobs have changed and write it in log file. I know how to write to log file, but I dont know how to detect which properties have changed.
I could go and write 30 if statements in which I would compare starting point with ending point but I have 30 properties and it would be a complete mess.
Any ideas?
Take a look at INotifyPropertyChanged:https://learn.microsoft.com/en-us/dotnet/framework/winforms/how-to-implement-the-inotifypropertychanged-interface
Example
using log4net;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(Form1).FullName);
public PersonViewPresenter Presenter { get; private set; }
public Form1()
{
InitializeComponent();
Presenter = new PersonViewPresenter();
Presenter.PropertyChanged += Presenter_PropertyChanged;
AddBindings();
}
private void Presenter_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Logger.Info($"Property changed {e.PropertyName}");
}
private void AddBindings()
{
_firstnameTextbox.DataBindings.Add(new Binding(nameof(_firstnameTextbox.Text), Presenter, nameof(Presenter.FirstName), false, DataSourceUpdateMode.OnValidation));
_lastnameTextBox.DataBindings.Add(new Binding(nameof(_lastnameTextBox.Text), Presenter, nameof(Presenter.LastName), false, DataSourceUpdateMode.OnValidation));
}
}
}
ViewPresenter implementation
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WindowsFormsApp1
{
public class PersonViewPresenter : ViewPresenterBase
{
private string _lastName;
private string _firstName;
public string FirstName
{
get => _firstName; set
{
if (_firstName != value)
{
_firstName = value;
NotifyPropertyChanged();
}
}
}
public string LastName
{
get => _lastName; set
{
if (_lastName != value)
{
_lastName = value;
NotifyPropertyChanged();
}
}
}
}
public abstract class ViewPresenterBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I am trying to implement validation within a WPF application using MVVM, I believe that I have the validation set up correctly but when I test it it doesn't seem to give me a red outline on the text box as many examples I've found online do (Such as https://www.youtube.com/watch?v=OOHDie8BdGI).
For simplicity I have narrowed it down to one criterion which is that the textbox for Forename is not left blank and removed the other properties. The only difference I am aware of between the examples in guides I have been using and my own application is that my Model is held on a server whereas the View and ViewModel are client side, could this be what is causing the issues?
Any help would be greatly appreciated as I've been struggling with this for a few days now, thanks!
RegistrationModel (Server side)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Linq;
using System.Web;
namespace ScrumManagementWCFServices.Services.Registration
{
[DataContract]
public class RegistrationModel : IDataErrorInfo, INotifyPropertyChanged
{
private string forename;
[DataMember]
public string Forename
{
get
{
return forename;
}
set
{
forename = value;
NotifyPropertyChanged("Forename");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region IDataErrorInfo Members
string System.ComponentModel.IDataErrorInfo.Error
{
get { return null; }
}
string System.ComponentModel.IDataErrorInfo.this[string propertyName]
{
get
{
return GetValidationError(propertyName);
}
}
#endregion
#region Validation
static readonly string[] ValidatedProperties = {/* "Email", */"Forename"/*, "Surname", "Password", "ConPassword"*/};
public bool IsValid
{
get
{
foreach (string property in ValidatedProperties)
if (GetValidationError(property) != null)
return false;
return true;
}
}
string GetValidationError(String propertyName)
{
string error = null;
switch (propertyName)
{
case "Forename":
error = validateForename();
break;
}
return error;
}
private string validateForename()
{
if (String.IsNullOrWhiteSpace(Forename))
{
return "Customer name cannot be empty.";
}
return null;
}
}
}
RegistrationPage (View - Client side)
<Page x:Class="ScrumManagementApplication.Pages.LoginAndRegistrationPage.View.RegistrationPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ScrumManagementApplication.Pages.LoginAndRegistrationPage.ViewModel"
mc:Ignorable="d"
d:DesignHeight="300"
Title="RegistrationView" Width="300">
<Page.Resources>
<local:RegistrationViewModel x:Key="DataContext"/>
</Page.Resources>
<Grid Background="#FFC0CAEC" DataContext="{StaticResource DataContext}" Margin="10">
<TextBox Text="{Binding RegistrationModel.Forename, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Page>
RegistrationViewModel (Client side)
using ScrumManagementApplication.WCFRegistrationServiceReference;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.ComponentModel;
using ScrumManagementApplication.Pages.LoginAndRegistrationPage.View;
using System.Windows;
namespace ScrumManagementApplication.Pages.LoginAndRegistrationPage.ViewModel
{
public class RegistrationViewModel : INotifyPropertyChanged
{
public RegistrationViewModel()
{
RegistrationModel = new RegistrationModel()
{
Forename = "Rick"
};
}
public RegistrationModel RegistrationModel
{
get;
set;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
Thanks in advance!
You need to expose a wrapper property and implement IDataErrorInfo on the view model or bind to the model directly. Validation will not work with bindings like {Binding RegistrationModel.Forename}
You can simplify things a bit with the System.ComponentModel.DataAnnotations Namespace. For example, if you decorate your Forename property with a RequiredAttribute, you will see your required red error outline on your TextBox when the field is left empty:
[DataMember]
[Required(ErrorMessage="Customer name cannot be empty.")]
public string Forename
{
get
{
return forename;
}
set
{
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) { MemberName = "Forename" });
forename = value;
NotifyPropertyChanged("Forename");
}
}
You can find out more details from the Using Data Annotations to Customize Data Classes page on MSDN. You could of course refactor this to use a single method that both validates and notifies the
INotifyPropertyChanged interface.
Without inherit but only with reflection is it possible to dynamically change the code of a method in C#?
something like :
nameSpaceA.Foo.method1 = aDelegate;
I cannot change/edit The Foo Class.
namespace nameSpaceA
{
class Foo
{
private void method1()
{
// ... some Code
}
}
}
My final objective is to change dynamicaly the code of :
public static IList<XPathNavigator> EnsureNodeSet(IList<XPathItem> listItems);
In System.Xml.Xsl.Runtime.XslConvert.cs
to turn :
if (!item.IsNode)
throw new XslTransformException(Res.XPath_NodeSetExpected, string.Empty);
into :
if (!item.IsNode)
throw new XslTransformException(Res.XPath_NodeSetExpected, item.value);
The first part of this answer is wrong, I'm only leaving it so that the evolution in the comments makes sense. Please see the EDIT(s).
You're not looking for reflection, but emission (which is the other way around).
In particular, there's a method that does just what you want, lucky you!
See TypeBuilder.DefineMethodOverride
EDIT:
Writing this answer, I just remembered that re-mix allows you to do this too. It's way harder though.
Re-mix is a framework that "simulates" mixins in C#. In its basic aspect, you can think of it as interfaces with default implementations. If you go further, it becomes much more than that.
EDIT 2: Here is an example of use for re-mix (implementing INotifyPropertyChanged on a class that doesn't support it, and has no idea of mixins).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Remotion.Mixins;
using System.ComponentModel;
using MixinTest;
[assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))]
namespace MixinTest
{
//[Remotion.Mixins.CompleteInterface(typeof(INPCTester))]
public interface ICustomINPC : INotifyPropertyChanged
{
void RaisePropertyChanged(string prop);
}
//[Extends(typeof(INPCTester))]
public class INotifyPropertyChangedMixin : Mixin<object>, ICustomINPC
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string prop)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}
}
public class ImplementsINPCAttribute : UsesAttribute
{
public ImplementsINPCAttribute()
: base(typeof(INotifyPropertyChangedMixin))
{
}
}
//[ImplementsINPC]
public class INPCTester
{
private string m_Name;
public string Name
{
get { return m_Name; }
set
{
if (m_Name != value)
{
m_Name = value;
((ICustomINPC)this).RaisePropertyChanged("Name");
}
}
}
}
public class INPCTestWithoutMixin : ICustomINPC
{
private string m_Name;
public string Name
{
get { return m_Name; }
set
{
if (m_Name != value)
{
m_Name = value;
this.RaisePropertyChanged("Name");
}
}
}
public void RaisePropertyChanged(string prop)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
And the test:
static void INPCImplementation()
{
Console.WriteLine("INPC implementation and usage");
var inpc = ObjectFactory.Create<INPCTester>(ParamList.Empty);
Console.WriteLine("The resulting object is castable as INPC: " + (inpc is INotifyPropertyChanged));
((INotifyPropertyChanged)inpc).PropertyChanged += inpc_PropertyChanged;
inpc.Name = "New name!";
((INotifyPropertyChanged)inpc).PropertyChanged -= inpc_PropertyChanged;
Console.WriteLine();
}
static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Hello, world! Property's name: " + e.PropertyName);
}
//OUTPUT:
//INPC implementation and usage
//The resulting object is castable as INPC: True
//Hello, world! Property's name: Name
Please note that:
[assembly: Mix(typeof(INPCTester), typeof(INotifyPropertyChangedMixin))]
and
[Extends(typeof(INPCTester))] //commented out in my example
and
[ImplementsINPC] //commented out in my example
Have the exact same effect. It is a matter of where you wish to define that a particular mixin is applied to a particular class.
Example 2: overriding Equals and GetHashCode
public class EquatableByValuesMixin<[BindToTargetType]T> : Mixin<T>, IEquatable<T> where T : class
{
private static readonly FieldInfo[] m_TargetFields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
bool IEquatable<T>.Equals(T other)
{
if (other == null)
return false;
if (Target.GetType() != other.GetType())
return false;
for (int i = 0; i < m_TargetFields.Length; i++)
{
object thisFieldValue = m_TargetFields[i].GetValue(Target);
object otherFieldValue = m_TargetFields[i].GetValue(other);
if (!Equals(thisFieldValue, otherFieldValue))
return false;
}
return true;
}
[OverrideTarget]
public new bool Equals(object other)
{
return ((IEquatable<T>)this).Equals(other as T);
}
[OverrideTarget]
public new int GetHashCode()
{
int i = 0;
foreach (FieldInfo f in m_TargetFields)
i ^= f.GetValue(Target).GetHashCode();
return i;
}
}
public class EquatableByValuesAttribute : UsesAttribute
{
public EquatableByValuesAttribute()
: base(typeof(EquatableByValuesMixin<>))
{
}
}
That example is my implementation of the hands-on lab given with re-mix. You can find more information there.
I have a class that implements INotifyPropertyChanged.
I create an instance of a class in some viewModel.
Is it possible to remove this functionality from the class and inject it after the instance was created? I heard that ICustomTypeDescriptor would make this happen, but i dont know how to use it.
public class C : ICustomNotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int _id;
public string _name;
public int Id
{
get { return _id; }
set
{
if (_id == value)
{
return;
}
_id = value;
OnPropertyChanged("Id");
}
}
public string Name
{
get { return _name; }
set
{
if (_name == value)
{
return;
}
_name = value;
OnPropertyChanged("Name");
}
}
public void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
If you are just trying to prevent the notifications from being fired when the object is first created and properties set, you can add boolean flag(s) that is/are false until the properties have been set once. You only execute the notification if the flag is true.
Edit:
I don't think there's a clean way to get the functionality in there after removing all the INotifyPropertyChanged code, but there are many ways to control the functionality from outside the instance.
Please note that I wrote all this code in the text editor, not in VisualStudio; it has not been tested in any way.
Add a method to enable notifications:
public class OptionalNotification : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string name) ...
bool _shouldNotify;
public void EnableNotifications()
{
_shouldNotify = true;
}
string _someProperty;
public string SomeProperty
{
get { return _someProperty; }
set
{
if(_someProperty == value) return
_someProperty = value;
if(_shouldNotify) OnPropertyChanged("SomeProperty");
}
}
}
You could do the same thing without the method, if you knew at the time of instantiation whether or not the instance should produce notifications, in which case you'd just need a boolean parameter in the constructor.
Another variation would be to use the Factory pattern, where your Factory has internal access to the boolean flag and sets it upon construction.
Encapsulate the condition in a proxy:
public interface IEntity : INotifyPropertyChanged
{
string SomeProperty { get; set; }
}
public class Entity : IEntity
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name) ...
string _someProperty;
public string SomeProperty
{
get { return _someProperty; }
set
{
if(_someProperty == value) return
_someProperty = value;
OnPropertyChanged("SomeProperty");
}
}
}
public class EntityNotificationProxy : IEntity
{
IEntity _inner;
public EntityNotificationProxy(IEntity entity)
{
_inner = entity;
_inner.PropertyChanged += (o,e) => { if(ShouldNotify) OnPropertyChanged(o,e); }
}
public bool ShouldNotify { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(object sender, PropertChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null) handler(sender, e);
}
public string SomeProperty
{
get { return _inner.SomeProperty; }
set
{
if(_inner.SomeProperty == value) return
_inner.SomeProperty = value;
}
}
}
Here your consuming classes get the entity proxy instead of the entity itself (but is none the wiser because it references only IEntity when you program to interfaces/abstractions). The wrapping of the proxy can happen in a factory or through an IoC container/DI framework.
The main advantage to this approach is that your entity maintains a pure INotifyPropertyChanged implementation, and the conditional aspect is handled from without. Another advantage is that it helps to enforce programming to abstractions and inversion of control.
The main disadvantage is that you'll need to create proxies for each INotifyPropertyChanged implementation that you want to have this conditional behaviour.
Create a registry to keep track of what instances should or should not raise notifications:
public static class PropertyNotificationRegistry
{
static IDictionary<INotifyPropertyChanged, bool> _registeredClasses
= new Dictionary<INotifyPropertyChanged, bool>;
static void Register(INotifyPropertyChanged o, bool shouldNotify)
{
if(!(_registeredClasses.ContainsKey(o)) _registeredClasses.Add(o, shouldNotify);
// could also implement logic to update an existing class in the dictionary
}
public static void ShouldNotifyWhenPropertiesChange(this INotifyPropertyChanged o)
{
Register(o, true);
}
public static void ShouldNotNotifyWhenPropertiesChange(this INotifyPropertyChanged o)
{
Register(o, false);
}
public static void NotifyPropertyChanged(this INotifyPropertyChanged o, Action notificationAction)
{
if(_registeredClasses.ContainsKey(o))
{
bool shouldNotify = _registeredClasses.Where(x => x.Key == o).Single().Value;
if(shouldNotify) notificationAction();
}
}
}
public class EntityUsingNotificationRegistry : INotifyPropertyChanged
{
... // all the standard INotifyPropertyChanged stuff
string _someProperty;
public string SomeProperty
{
get { return _someProperty; }
set
{
if(_someProperty == value) return;
_someProperty = value;
this.NotifyPropertyChanged(() => OnPropertyChanged("SomeProperty"));
}
}
}
public class SomethingInstantiatingOurEntity
{
public void DoSomething()
{
var entity1 = new EntityUsingNotificationRegistry();
entity1.ShouldNotifyWhenPropertiesChange();
var entity2 = new EntityUsingNotificationRegistry();
entity2.ShouldNotNotifyWhenPropertiesChange();
entity1.SomeProperty = "arbitrary string"; // raises event
entity2.SomeProperty = "arbitrary string"; // does not raise event
var entity3 = new EntityUsingNotificationRegistry();
entity3.SomeProperty = "arbitrary string"; // does not raise event
entity3.ShouldNotifyWhenPropertiesChange();
entity3.SomeProperty = "another arbitrary string"; // now raises event
}
}
Now, the registry has a distinct shortcoming in that it holds references to every instance and will prevent those instances from being picked up by the garbage collector. There may be a solution to this by implementing the registry with WeakReferences, but I'm not up-to-snuff on their usage to recommend a particular implementation.
This will not work. You COULD subclass and inject it, but you would have to change the byte-code to make sure the proper methods are CALLED - and that is the harder method.