.NET, C#, MVVM, TextTemplate, XAML

Using TextTemplate to Generate Wrapper classes

Wrapping classes is sometimes necessary in development. The MVVM pattern usually wraps the model inside a viewmodel class for it tobe bindable. In brokered component we can’t expose a class from a referenced library unless we wrap it in a sealed class. The problem with wrapping is that we repeat the same code over and we expose properties and function with the same name and we have to retype it and it takes some amount of time.

The good news is that there’s an item in visual studio called TextTemplate. Text template is a scriptable file that can generate code for you and those generated files are usable within the assembly.

Now going back to the problem of wrapping classes. We as developers doesn’t want to spend time typing repetitive codes. Using reflection I managed to create a reusable script that can generate a wrapper class. This script will generate wrapped properties, methods, constructors and nested class. You can download the TextTemplate source code from my Github repo.

Basic Class Wrapping

Classes that will be wrapped within a wrapper:

public class User
{
public string FirstName { get; set; }

public string LastName { get; set; }

public string UserName { get; set; }

public int Role { get; set; }

public int InvalidLoginAttempt { get; set; }

}

public class Driver
{
public Driver(string name) { }

public Driver() { Nested = new SomeNestedClass(); }

public string DriverId { get; private set; }

public string DriverName { get; set; }

public string TruckNo { get; set; }

public SomeNestedClass Nested { get; set; }

public User UserInfo { get; set; }

public void StartShift(string p1, string p2, ref int odometer, params object[] args) { Console.WriteLine("StartShift"); }

public int EndShift(string p1, string p2, out int odometer) { Console.WriteLine("EndShift"); odometer = 1; return 0; }

public class SomeNestedClass
{
public string NestedValue { get; set; }

public string NestedName { get; set; }

public void Hello()
{
Console.WriteLine("Hello Nested World");
}
}
}

Wrapped Classes:

public sealed class Driver
{
#region Constructors

public DataModels.Driver driverDataModel;
public Driver(DataModels.Driver driver) { this.driverDataModel = driver; }
public Driver(System.String name)
{
driverDataModel = new DataModels.Driver(name);
}
public Driver()
{
driverDataModel = new DataModels.Driver();
}

#endregion Constructors

#region Properties

public System.String DriverId { get { return driverDataModel.DriverId; }  }
public System.String DriverName { get { return driverDataModel.DriverName; } set { driverDataModel.DriverName = value; } }
public System.String TruckNo { get { return driverDataModel.TruckNo; } set { driverDataModel.TruckNo = value; } }
private BasicClassWrapperSample.SomeNestedClass _Nested = null;
public BasicClassWrapperSample.SomeNestedClass Nested { get { if(_Nested == null) _Nested = new BasicClassWrapperSample.SomeNestedClass(driverDataModel.Nested); return _Nested; } set { _Nested = value; } }
private BasicClassWrapperSample.User _UserInfo = null;
public BasicClassWrapperSample.User UserInfo { get { if(_UserInfo == null) _UserInfo = new BasicClassWrapperSample.User(driverDataModel.UserInfo); return _UserInfo; } set { _UserInfo = value; } }

#endregion Properties

#region Methods

public void StartShift (System.String p1, System.String p2, ref System.Int32 odometer, params System.Object[] args) => driverDataModel.StartShift(p1, p2, ref odometer, args);
public System.Int32 EndShift (System.String p1, System.String p2, out System.Int32 odometer) => driverDataModel.EndShift(p1, p2, out odometer);

#endregion Methods
}
public sealed class SomeNestedClass
{
#region Constructors

public DataModels.Driver.SomeNestedClass somenestedclassDataModel;
public SomeNestedClass(DataModels.Driver.SomeNestedClass somenestedclass) { this.somenestedclassDataModel = somenestedclass; }
public SomeNestedClass()
{
somenestedclassDataModel = new DataModels.Driver.SomeNestedClass();
}

#endregion Constructors

#region Properties

public System.String NestedValue { get { return somenestedclassDataModel.NestedValue; } set { somenestedclassDataModel.NestedValue = value; } }
public System.String NestedName { get { return somenestedclassDataModel.NestedName; } set { somenestedclassDataModel.NestedName = value; } }

#endregion Properties

#region Methods

public void Hello () => somenestedclassDataModel.Hello();

#endregion Methods
}

public sealed class User
{
#region Constructors

public DataModels.User userDataModel;
public User(DataModels.User user) { this.userDataModel = user; }
public User()
{
userDataModel = new DataModels.User();
}

#endregion Constructors

#region Properties

public System.String FirstName { get { return userDataModel.FirstName; } set { userDataModel.FirstName = value; } }
public System.String LastName { get { return userDataModel.LastName; } set { userDataModel.LastName = value; } }
public System.String UserName { get { return userDataModel.UserName; } set { userDataModel.UserName = value; } }
public System.Int32 Role { get { return userDataModel.Role; } set { userDataModel.Role = value; } }
public System.Int32 InvalidLoginAttempt { get { return userDataModel.InvalidLoginAttempt; } set { userDataModel.InvalidLoginAttempt = value; } }

#endregion Properties

#region Methods

#endregion Methods
}

Wrapping Model within ViewModel

//Model
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public int Role { get; set; }
public int InvalidLoginAttempt { get; set; }
}

//Wrapped ViewModel
public sealed class UserViewModel : ViewModelBase
{
#region Constructors

public DataModels.User userDataModel;
public UserViewModel(DataModels.User user) { this.userDataModel = user; }
public UserViewModel()
{
userDataModel = new DataModels.User();
}

#endregion Constructors

#region Properties

public System.String FirstName { get { return userDataModel.FirstName; } set { userDataModel.FirstName = value; OnPropertyChanged(); } }
public System.String LastName { get { return userDataModel.LastName; } set { userDataModel.LastName = value; OnPropertyChanged(); } }
public System.String UserName { get { return userDataModel.UserName; } set { userDataModel.UserName = value; OnPropertyChanged(); } }
public System.Int32 Role { get { return userDataModel.Role; } set { userDataModel.Role = value; OnPropertyChanged(); } }
public System.Int32 InvalidLoginAttempt { get { return userDataModel.InvalidLoginAttempt; } set { userDataModel.InvalidLoginAttempt = value; OnPropertyChanged(); } }

#endregion Properties
}

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s