I would like to pass a class type as a parameter so it can use a share method to do similar jobs.
At first, processContact will be call and do the following, there will be more and more similar method like ProcessGeneralAccountContact,ProcessOperationalIntegrityAccountContact and ProcessPaAccountContact, they are just updating/creating records in different Accounts. Every of them has a individual Process,Create and Update process, I would like to create a share method for processes.
e.g.
I can call create/update all contact by just doing this
ProcessContact(sourceContact, GeneralAccountManager, GeneralAccountField, GeneralAccountFieldAttribute),
ProcessContact(sourceContact, PaAccountManager,PaAccountField,PaAccountFieldAttribute),
ProcessContact(sourceContact,HrAccountManager,HrAccountField,HrAccountFieldAttribute),
Is it possible to pass a class type like Process(sourceContact,typeof(GeneralAccountManager),typeof(GeneralAccountField),typeof(GeneralAccountFieldAttribute)) to add flexibility to the code to avoid code repetition?
Thanks so much guys!
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Web.Http;
using System.Web.Script.Serialization;
using ClientProject.Common.Api;
using u2ool.Data;
using u2ool.Logging;
using WebhookApiUpdater.Infrastructure;
using WebhookApiUpdater.Models;
namespace WebhookApiUpdater.Controllers
{
public class UpdateController : ApiController
{
[HttpPost]
public HttpStatusCode Record()
{
var sourceContact = GetSourceModel(Request);
return ProcessContact(sourceContact);
}
private HttpStatusCode ProcessContact(ContactModel sourceContact)
{
List<HttpStatusCode> returnedHttpStatusCodes = new List<HttpStatusCode>
{ // each of the account has to be processed separately as the Managers are unique and have no common denominator class
ProcessGeneralAccountContact(sourceContact),
ProcessOperationalIntegrityAccountContact(sourceContact),
ProcessPaAccountContact(sourceContact),
ProcessInternalCommsProjectsContact(sourceContact),
ProcessEaAccountContact(sourceContact),
ProcessHrAccountContact(sourceContact)
//this is what I want to do
Process(sourceContact,typeof(GeneralAccountManager),typeof(GeneralAccountField),typeof(GeneralAccountFieldAttribute))
};
return returnedHttpStatusCodes.All(x => x == HttpStatusCode.Accepted)
? HttpStatusCode.Accepted
: returnedHttpStatusCodes.FirstOrDefault(x => x != HttpStatusCode.Accepted);
}
private HttpStatusCode Process(ContactModel sourceContact, Type accountManager,Type accountField, Type accountFieldAttribute)
{
var currentAccountManager = Activator.CreateInstance(accountManager);
Enum currentAccountField = (Enum)Enum.ToObject(accountField,accountField);
var currentAccountFieldAttribute = Activator.CreateInstance(accountFieldAttribute);
((Manager<currentAccountField, currentAccountFieldAttribute>)currentAccountManager).data
var generalAccountContact = GeneralAccountManager.Database.QueryContacts<ContactModel>(GeneralAccountFilter.Eq(GeneralAccountField.EmployeeID, sourceContact.EmployeeID), 1).ToList();
if (generalAccountContact.Count == 0 || generalAccountContact.First().ReferenceID == Guid.Empty)
return CreateGeneralAccountContact(sourceContact);
// else
sourceContact.ReferenceID = generalAccountContact.First().ReferenceID;
return UpdateGeneralAccountContact(sourceContact);
}
private HttpStatusCode ProcessHrAccountContact(ContactModel sourceContact)
{
var hrAccountContact = HrAccountManager.Database.QueryContacts<ContactModel>(HrAccountFilter.Eq(HrAccountField.EmployeeID, sourceContact.EmployeeID), 1).ToList();
if (hrAccountContact.Count == 0 || hrAccountContact.First().ReferenceID == Guid.Empty)
return CreateHrAccountContact(sourceContact);
// else
sourceContact.ReferenceID = hrAccountContact.First().ReferenceID;
return UpdateHrAccountContact(sourceContact);
}
private HttpStatusCode ProcessEaAccountContact(ContactModel sourceContact)
{
var eaAccountContact = EaAccountManager.Database.QueryContacts<ContactModel>(EaAccountFilter.Eq(EaAccountField.EmployeeID, sourceContact.EmployeeID), 1).ToList();
if (eaAccountContact.Count == 0 || eaAccountContact.First().ReferenceID == Guid.Empty)
return CreateEaAccountContact(sourceContact);
// else
sourceContact.ReferenceID = eaAccountContact.First().ReferenceID;
return UpdateEaAccountContact(sourceContact);
}
private HttpStatusCode ProcessInternalCommsProjectsContact(ContactModel sourceContact)
{
var internalCommsProjectsContact = InternalCommsProjectsAccountManager.Database.QueryContacts<ContactModel>(InternalCommsProjectsAccountFilter.Eq(InternalCommsProjectsAccountField.EmployeeID, sourceContact.EmployeeID), 1).ToList();
if (internalCommsProjectsContact.Count == 0 || internalCommsProjectsContact.First().ReferenceID == Guid.Empty)
return CreateInternalCommsProjectsContact(sourceContact);
// else
sourceContact.ReferenceID = internalCommsProjectsContact.First().ReferenceID;
return UpdateInternalCommsProjectsContact(sourceContact);
}
private HttpStatusCode ProcessGeneralAccountContact(ContactModel sourceContact)
{
var generalAccountContact = GeneralAccountManager.Database.QueryContacts<ContactModel>(GeneralAccountFilter.Eq(GeneralAccountField.EmployeeID, sourceContact.EmployeeID), 1).ToList();
if (generalAccountContact.Count == 0 || generalAccountContact.First().ReferenceID == Guid.Empty)
return CreateGeneralAccountContact(sourceContact);
// else
sourceContact.ReferenceID = generalAccountContact.First().ReferenceID;
return UpdateGeneralAccountContact(sourceContact);
}
private HttpStatusCode ProcessOperationalIntegrityAccountContact(ContactModel sourceContact)
{
var operationalIntegrityAccountContact = OperationalIntegrityAccountManager.Database.QueryContacts<ContactModel>(OperationalIntegrityAccountFilter.Eq(OperationalIntegrityAccountField.EmployeeID, sourceContact.EmployeeID), 1).ToList();
if (operationalIntegrityAccountContact.Count == 0 || operationalIntegrityAccountContact.First().ReferenceID == Guid.Empty)
return CreateOperationalIntegrityAccountContact(sourceContact);
// else
sourceContact.ReferenceID = operationalIntegrityAccountContact.First().ReferenceID;
return UpdateOperationalIntegrityAccountContact(sourceContact);
}
private HttpStatusCode ProcessPaAccountContact(ContactModel sourceContact)
{
var paAccountContact = PaAccountManager.Database.QueryContacts<ContactModel>(PaAccountFilter.Eq(PaAccountField.EmployeeID, sourceContact.EmployeeID), 1).ToList();
if (paAccountContact.Count == 0 || paAccountContact.First().ReferenceID == Guid.Empty)
return CreatePaAccountContact(sourceContact);
// else
sourceContact.ReferenceID = paAccountContact.First().ReferenceID;
return UpdatePaAccountContact(sourceContact);
}
private HttpStatusCode UpdateGeneralAccountContact(ContactModel sourceContact)
{
Action<ContactModel> generalAccountUpdateAction = update => GeneralAccountManager.Database.UpdateContact(sourceContact.ReferenceID, sourceContact);
return UpdateContact(generalAccountUpdateAction, sourceContact);
}
private HttpStatusCode UpdateOperationalIntegrityAccountContact(ContactModel sourceContact)
{
Action<ContactModel> operationalIntegrityUpdateAction = update => OperationalIntegrityAccountManager.Database.UpdateContact(sourceContact.ReferenceID, sourceContact);
return UpdateContact(operationalIntegrityUpdateAction, sourceContact);
}
private HttpStatusCode UpdatePaAccountContact(ContactModel sourceContact)
{
Action<ContactModel> paAccountUpdateAction = update => PaAccountManager.Database.UpdateContact(sourceContact.ReferenceID, sourceContact);
return UpdateContact(paAccountUpdateAction, sourceContact);
}
private HttpStatusCode UpdateInternalCommsProjectsContact(ContactModel sourceContact)
{
Action<ContactModel> internalCommsProjectsAccountAction = update => InternalCommsProjectsAccountManager.Database.UpdateContact(sourceContact.ReferenceID, sourceContact);
return UpdateContact(internalCommsProjectsAccountAction, sourceContact);
}
private HttpStatusCode UpdateEaAccountContact(ContactModel sourceContact)
{
Action<ContactModel> eaAccountAccountUpdateAction = update => EaAccountManager.Database.UpdateContact(sourceContact.ReferenceID, sourceContact);
return UpdateContact(eaAccountAccountUpdateAction, sourceContact);
}
private HttpStatusCode UpdateHrAccountContact(ContactModel sourceContact)
{
Action<ContactModel> hrAccountAccountUpdateAction = update => HrAccountManager.Database.UpdateContact(sourceContact.ReferenceID, sourceContact);
return UpdateContact(hrAccountAccountUpdateAction, sourceContact);
}
private HttpStatusCode UpdateContact(Action<ContactModel> dbUpdateAction, ContactModel sourceContact)
{
try
{
dbUpdateAction(sourceContact);
return HttpStatusCode.Accepted;
}
catch (Exception e)
{
Log.Exception(e);
return HttpStatusCode.InternalServerError;
}
}
private HttpStatusCode CreateGeneralAccountContact(ContactModel sourceContact)
{
Action<ContactModel> generalAccountCreateAction = create => GeneralAccountManager.Database.AddContact(sourceContact);
return CreateContact(generalAccountCreateAction, sourceContact);
}
private HttpStatusCode CreateOperationalIntegrityAccountContact(ContactModel sourceContact)
{
Action<ContactModel> operationalIntegrityAccountCreateAction = create => OperationalIntegrityAccountManager.Database.AddContact(sourceContact);
return CreateContact(operationalIntegrityAccountCreateAction, sourceContact);
}
private HttpStatusCode CreatePaAccountContact(ContactModel sourceContact)
{
Action<ContactModel> paAccountManagerCreateAction = create => PaAccountManager.Database.AddContact(sourceContact);
return CreateContact(paAccountManagerCreateAction, sourceContact);
}
private HttpStatusCode CreateInternalCommsProjectsContact(ContactModel sourceContact)
{
Action<ContactModel> internalCommsProjectsCreateAction = create => InternalCommsProjectsAccountManager.Database.AddContact(sourceContact);
return CreateContact(internalCommsProjectsCreateAction, sourceContact);
}
private HttpStatusCode CreateEaAccountContact(ContactModel sourceContact)
{
Action<ContactModel> eaAccountContactCreateAction = create => EaAccountManager.Database.AddContact(sourceContact);
return CreateContact(eaAccountContactCreateAction, sourceContact);
}
private HttpStatusCode CreateHrAccountContact(ContactModel sourceContact)
{
Action<ContactModel> hrAccountContactCreateAction = create => HrAccountManager.Database.AddContact(sourceContact);
return CreateContact(hrAccountContactCreateAction, sourceContact);
}
private HttpStatusCode CreateContact(Action<ContactModel> dbUCreateAction, ContactModel sourceContact)
{
try
{
dbUCreateAction(sourceContact);
return HttpStatusCode.Accepted;
}
catch (Exception e)
{
Log.Exception(e);
return HttpStatusCode.InternalServerError;
}
}
private ContactModel GetSourceModel(HttpRequestMessage request)
{
Log.Information("Webhooks - Message recieved");
var body = request.Content.ReadAsStringAsync().Result;
Log.Information(new LogCategory("Contact to process: "), body);
var bodyDeserialised = new JavaScriptSerializer().Deserialize<BodyDeserialised>(body);
var contact = new ContactModel();
foreach (var datum in bodyDeserialised.Data)
{
var propertyInfo = contact.GetType().GetProperty(datum.Name.Replace(" ", string.Empty));
if (propertyInfo != null)
propertyInfo.SetValue(contact, datum.Value, null);
}
return contact;
}
GeneralAccountManager.cs,HrAccountManager.cs etc etc, they all have same set of properties and method, just the naming is different.
using System;
using ClientProject.Common.Api;
using u2ool.Settings;
namespace WebhookApiUpdater.Infrastructure
{
public enum GeneralAccountField
{
City,
CompanyDescription,
Country,
CreateDate,
Department,
EmailAddress,
EmployeeID,
FunctionalDivision,
Gender,
GNADate,
GNA,
GroupDivision,
HasMailbox,
HireDate,
ID,
IsManager,
IsSLT,
LastModified,
LastName,
OCSAddress,
OptOutDate,
OptedOut,
Optedback,
OrganisationalRelationship,
PersonID,
PersonStatus,
PreferredName,
ReferenceID,
Source,
Version,
JobProfile
}
[AttributeUsage(AttributeTargets.Property)]
public class GeneralAccountFieldAttribute : Attribute, IMappableAttribute<GeneralAccountField>
{
public GeneralAccountField Field { get; }
/// <summary>
/// When using the FormMapping.AddFormParameters method, set to false to skip binding this property.
/// </summary>
public bool AutoBind { get; } = true;
/// <param name="field">Specify a DatabaseField that this property is bound to</param>
public GeneralAccountFieldAttribute(GeneralAccountField field)
{
Field = field;
}
}
public class GeneralAccountManager : Manager<GeneralAccountField, GeneralAccountFieldAttribute> { }
public class GeneralAccountMapping : Mapping<GeneralAccountField, GeneralAccountFieldAttribute> { }
public class GeneralAccountFilter : Filter<GeneralAccountField> { }
public class GeneralAccountSettings : EngageSettings<GeneralAccountField>
{
public GeneralAccountSettings(ISettingsContainer container, string prefix = null) : base(container, prefix)
{
}
}
}