There are several approaches to solving this problem, one of which is using the principles of SOLID along with Software Design Patterns .
We can start with the principle of "Single Responsability" (the "S" of SOLID) or single responsibility and ask: "Whose responsibility is it to create a JsonClipAlerta?" Perhaps an object factory would be better suited to this task. "How many factories are there in the program?" Probably only one. "Will this factory have any ' suppliers ' of information?" Perhaps we can contract (or "inject") suppliers through a contract (or "interface").
Soon we can use a combination of patterns : let's then create a single instance object factory that will receive via dependency injection the two information providers, let's combine a Singleton with Factory Method Pattern Dependency Injection Design Pattern for high cohesion terms, that is, each class with a responsibility and terms low matching, that is, each class does not depend on another class, other than interfaces, which is the "Dependency inversion principle" of SOLID that says that we must depend on abstractions (interfaces) rather than implementations (classes).
Our goal is to create Json as follows:
JsonClipAlerta json = JsonClipAlertaFactory.Instance
.CreateJsonClipAlerta(new JsonClipArguments { Id = 100, InitialDate = DateTime.Now });
So a possible factory solution would be:
public sealed class JsonClipAlertaFactory
{
// providers que serão inicializados no construtor
private readonly IProviderClipAlerta providerClip;
private readonly IRepositorioEnderecoEletronico providerEndereco;
// Factory method que cria os objetos
public JsonClipAlerta CreateJsonClipAlerta(JsonClipArguments args)
{
ClipAlerta clip = this.providerClip.GetClipAlerta(args.Id);
var jsonClip = new JsonClipAlerta()
{
// Informações vindas do primeiro provider
Id = clip.Id,
Expressoes = clip.Expressoes,
// Informações vindas do segundo provider
EnderecosEletronicos = this.providerEndereco
.RetornaColecao(clip.EnderecosEletronicos.ToList())
};
return jsonClip;
}
// Singleton com construtor privado que recebe os providers
private JsonClipAlertaFactory(
IProviderClipAlerta providerClip,
IRepositorioEnderecoEletronico providerEndereco)
{
this.providerClip = providerClip;
this.providerEndereco = providerEndereco;
}
public static JsonClipAlertaFactory Instance
{
get { return Nested.instance; }
}
private class Nested
{
// Construtor estático para dizer ao compilador C#
// não marcar tipo como 'beforefieldinit'
static Nested() { }
// Passando os providers para o construtor privado
internal static readonly JsonClipAlertaFactory instance =
new JsonClipAlertaFactory(
new ProviderClipAlerta(),
new RepositorioEnderecoEletronico());
}
}
With the following classes, from illustration to our example above:
// Classes de 'ilustração' usada na nossa Factory acima
public class ClipAlerta
{
public long Id { get; set; }
public IList<ExpressoesStruct> Expressoes { get; set; }
public IList<string> EnderecosEletronicos { get; set; }
}
// Interfaces e classes dos providers
public interface IProviderClipAlerta
{
ClipAlerta GetClipAlerta(long id);
}
public interface IRepositorioEnderecoEletronico
{
IList<string> RetornaColecao(IList<string> listaEmails);
}
public class ProviderClipAlerta : IProviderClipAlerta
{
public ClipAlerta GetClipAlerta(long id)
{
throw new NotImplementedException();
}
}
public class RepositorioEnderecoEletronico : IRepositorioEnderecoEletronico
{
public IList<string> RetornaColecao(IList<string> listaEmails)
{
throw new NotImplementedException();
}
}
// Struct para auxiliar a passagem de parametros
public struct JsonClipArguments
{
public long Id;
public DateTime InitialDate;
// outros parametros..
}