Sto lavorando al refactoring di un'app Web di sincronizzazione utilizzata dalla nostra azienda. Attualmente è semplicemente un insieme di controller che attivano una serie di helper che attraversano una lunga catena di istruzioni di tipo if-else.
Sto tentando di creare un wrapper attorno al riferimento web SalesForce Soap, ma sto riscontrando qualche problema con un buon modello di ereditarietà.
Quando si usa il wrapper, voglio essenzialmente poter dire qualcosa del tipo
var SalesForce = new SalesForceApi(Username, Password, Url);
var tmp1 = SalesForce.Users.GetUsers();
// or
var tmp2 = SalesForce.Users.GetUserById(id);
// or
var tmp3 = SalesForce.Organizations.GetOrganizations();
// you get the picture.
Idealmente vorrei creare un'istanza dell'oggetto SalesForceApi, e semplicemente passare la sua connessione attiva attraverso tutte le sue diverse richieste e tipi di richieste. Sono solo un po 'confuso sulla porzione di implementazione.
Penso di essere in qualche modo nella giusta direzione.
Ho creato una classe astratta chiamata Base
che contiene un oggetto chiamato Binding
con il tipo SforceService
. Contiene metodi di accesso e disconnessione utilizzati per creare una connessione attiva. Quando viene creato un oggetto SalesForceApi
con nome utente, password e url, questi vengono passati alle sottoclassi come Users
che ereditano la classe Base
. Questi valori vengono quindi passati alla classe Base
per creare un oggetto vincolante attivo.
Modifica
Ecco alcune lezioni che ho creato che mi danno un po 'di un metodo per realizzare ciò che voglio.
La mia Main SalesForce class (o SalesForceApi)
namespace SyncTool.Core.Services.SalesForce
{
public interface ISalesForce
{
IAccounts Accounts { get; }
IAttachments Attachments { get; }
ICases Cases { get; }
IContacts Contacts { get; }
IGroups Groups { get; }
IRecordTypes RecordTypes { get; }
IUsers Users { get; }
}
public class SalesForceApi:ISalesForce
{
public IAccounts Accounts { get; set; }
public IAttachments Attachments { get; set; }
public ICases Cases { get; set; }
public IContacts Contacts { get; set; }
public IGroups Groups { get; set; }
public IRecordTypes RecordTypes { get; set; }
public IUsers Users { get; set; }
public SalesForceApi()
{
Accounts = new Accounts();
Attachments = new Attachments();
Cases = new Cases();
Contacts = new Contacts();
Groups = new Groups();
RecordTypes = new RecordTypes();
Users = new Users();
}
}
}
La classe Base richiesta
namespace SyncTool.Core.Services.SalesForce.Requests
{
public abstract class RequestBase: IDisposable
{
private const string User = "[email protected]";
private const string Pass = "foobar";
private const string Url = "url";
public SforceService Binding;
public Logger Logger = LogManager.GetCurrentClassLogger();
protected RequestBase()
{
Login(User, Pass, Url);
}
public bool Login(string username, string password, string url)
{
Binding = new SforceService { Url = url, Timeout = 60000 };
LoginResult lr;
try
{
lr = Binding.login(username, password);
}
catch (SoapException e)
{
Logger.Error("An error has occurred",e);
return false;
}
Binding.SessionHeaderValue = new SessionHeader { sessionId = lr.sessionId };
Binding.Url = lr.serverUrl;
return true;
}
public bool Logout()
{
try
{
Binding.logout();
return true;
}
catch (SoapException)
{
return false;
}
}
public void Dispose()
{
Logout();
Binding.Dispose();
}
}
}
Ed ecco un esempio di una delle classi di richieste
namespace SyncTool.Core.Services.SalesForce.Requests
{
public interface IUsers
{
List<User> GetUsers();
User GetUserById(string id);
List<User> GetUsersByEmail(string email);
User GetUserByEmail(string email);
}
public class Users : RequestBase, IUsers
{
public List<User> GetUsers()
{
try
{
const string soqlQuery = "SELECT Id, Name, FirstName, LastName, Email FROM User";
var qResult = Binding.query(soqlQuery);
var done = false;
if (qResult.size <= 0) return new List<User>();
var users = new List<User>();
while (!done)
{
var records = (qResult.records.Cast<User>().ToList());
users.AddRange(records);
if (qResult.done)
done = true;
else
qResult = Binding.queryMore(qResult.queryLocator);
}
return users;
}
catch (SoapException e)
{
Logger.ErrorException("An unexpected error occurred when retreiving users.",e);
return null;
}
}
public User GetUserById(string id)
{
try
{
var qResult = Binding.query("SELECT Id, Name, FirstName, LastName, Email FROM User WHERE Id='" + id + "'");
if (qResult.size <= 0) return new User();
var records = (qResult.records.Cast<User>().ToList());
return records.Count > 0 ? records.FirstOrDefault() : new User();
}
catch (SoapException e)
{
Logger.ErrorException("An unexpected error occurred when retreiving users.", e);
return null;
}
}
public List<User> GetUsersByEmail(string email)
{
try
{
var qResult = Binding.query("SELECT Id, Name, FirstName, LastName, Email FROM User WHERE Email='" + email + "'");
if (qResult.size <= 0) return new List<User>();
var records = (qResult.records.Cast<User>().ToList());
return records;
}
catch (SoapException e)
{
Logger.ErrorException("An unexpected error occurred when retreiving users.", e);
return null;
}
}
public User GetUserByEmail(string email)
{
try
{
var qResult = Binding.query("SELECT Id, Name, FirstName, LastName, Email FROM User WHERE Email='" + email + "'");
if (qResult.size <= 0) return new User();
var records = (qResult.records.Cast<User>().ToList());
return records.Count > 0 ? records.FirstOrDefault() : new User();
}
catch (SoapException e)
{
Logger.ErrorException("An unexpected error occurred when retreiving users.", e);
return null;
}
}
}
}