Populating a class whose data is stored in an external application Im currently working on a system that will communicate with other systems via webservice (or some sort of communication). I have a system that stores all user data already and don't want to duplicate data in this new system so I have come up with a way of accessing the data when needed. 

In my current system I am planning to just store the user ID from the user system and fetch the data when required. My question is, is the following code considered acceptable/understood or would you suggest an alternative way of achieving this?



public class Person
{
    private string id;
    [Transient]
    private string name;
    [Transient]
    private bool isPopulated;

    public Person(string id){
       this.id = id;
    }

    public string Id{get;set;}

    public string Name{
        get{
            init();
            return this.name;
        }
        set{
            this.name = value;
        }
    }

    private void init(){
        if(!isPopulated){
            TempPerson tempPerson = UserService.getPerson(this.id);
            this.name = tempPerson.Name;
            this.isPopulated = true;
        }
    }
}


Is there a better way to do this and are there any problem with this way?
What you have implemented is a sort of Active Record where the record itself knows how to communicate with the storage. 

What is bad about your design is that this kind of code will be extremely hard to unit test. Imagine that you need to write a unit test for a class that uses Person objects. How can you prevent it from calling UserService?

The proper solution for your problem depends on use cases. 


Will you need to update your entities and propagate those changes back to server? 
Can you load several entities at once using methods other than UserService.getPerson(this.id);?
What is the lifetime of the entities loaded?


Generally the most flexible solution (as I see it) would be to implement a repository and unit-of-work pattern (similar to ISession in NHibernate or DbContext in Entity Framework). Basically it's better not to hide communication with 3rd-party but rather expose it in such a way that you have maximum control and flexibility.

Primitive implementation may look like:

public class Person
{
    public string Id { get; set; }

    public string Name { get; set; }
}

public interface ISessionFactory
{
    IUserServiceSession CreateSession();
}

public interface IUserServiceSession
{
    Person GetPerson(string id);
}

public class SessionFactory : ISessionFactory
{
    public IUserServiceSession CreateSession()
    {
        UserService userService = new UserService(); //better use dependency injection, or cache it once if it's thread-safe.
        return new UserServiceSession(userService);
    }
}

public class UserServiceSession : IUserServiceSession
{
    private readonly Dictionary&lt;string, Person&gt; _cache = new Dictionary&lt;string, Person&gt;();
    private readonly UserService _userService;

    public UserServiceSession(UserService userService)
    {
        _userService = userService;
    }

    public Person GetPerson(string id)
    {
        Person result;
        if (!_cache.TryGetValue(id, out result))
            result = _cache[id] = _userService.getPerson(id);

        return result;
    }
}