I'm working on refactoring a synchronization web app that our company uses. Currently it's merely a set of controllers that fire up a set of helpers that go through a long chain of if-else type statements.
I'm attempting to build a wrapper around the SalesForce Soap web reference, but I'm having some trouble coming up with a good inheritance model.
When using the wrapper, I want to essentially be able to say something like
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.
Ideally I would want to instantiate the SalesForceApi object, and simply pass its active connection through all of it's different requests and request types. I'm just a bit fuzzy on the implementation portion.
I think I'm somewhat getting into the right direction.
I created an Abstract class called Base
that contains an object called Binding
with the type SforceService
. It contains login and logout methods that are used to create an active connection. When a SalesForceApi
object is created with the username, password, and url, these are passed to the sub classes like Users
which inherit the Base
class. These values are then passed to the Base
class to create an active binding object.
Edit
Here are a few classes I built that give me somewhat of a method of accomplishing what I want.
My Main SalesForce class (or 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(); } } }
The Request Base class
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(); } } }
And here's an example of one of the request classes
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; } } } }