J'ai les interfaces suivantes définies:
public interface IAudit {
DateTime DateCreated { get; set; }
}
public interface IAuditable {
IAudit Audit { get; set; }
}
L’interface IAuditable
indique les classes pour lesquelles je vais avoir un Audit
. L'interface IAudit
est la Audit
réelle pour cette classe. Par exemple, disons que j'ai les implémentations suivantes:
public class User : IAuditable {
public string UserName { get; set; }
public UserAudit Audit { get; set; }
}
public class UserAudit : IAudit {
public string UserName { get; set; }
public DateTime DateCreated { get; set; }
public UserAdit(User user) {
UserName = user.UserName;
}
}
Maintenant, étant donné un objet qui est IAuditable
(User
d'en haut), j'aimerais pouvoir créer une intance de IAudit
(UserAdit d'en haut) en introduisant l'objet IAuditable
dans le constructeur. Idéalement, j'aurais quelque chose comme:
if (myObject is IAuditable) {
var audit = new IAudit(myObject) { DateCreated = DateTime.UtcNow }; // This would create a UserAudit using the above example
}
Cependant, j'ai un tas de problèmes:
IAudit
s'applique à quelle IAuditable
IAudit
doit avoir un constructeur qui prend une IAuditable
Je suis sûr que c'est un motif de conception que beaucoup ont eu auparavant mais je n'arrive pas à comprendre. J'apprécierais vraiment si quelqu'un pouvait me montrer comment cela peut être réalisé.
Aucun endroit dans le code ne définit-il quel IAudit s'applique à quel IAuditable Je ne peux pas spécifier que l'interface IAudit doit avoir un constructeur qui prend une IAuditable
Vous pouvez résoudre ces deux problèmes en ajoutant une fonction CreateAudit()
à votre IAuditable
. Vous obtiendrez alors une IAudit
créée à partir de la IAuditable
. En prime, si vous souhaitez stocker une référence à la variable IAudit
dans la variable IAuditable
(ou l'inverse) afin que vous puissiez les relier les unes aux autres, il est assez facile de faire appel à une classe d'implémentation. Vous pouvez également ajouter GetAuditable()
à IAudit
pour obtenir la IAuditable
à partir de laquelle elle a été créée, par exemple.
Une implémentation simple ressemblerait à ceci (sur une classe implémentant IAuditable):
public IAudit CreateAudit()
{
UserAudit u = new UserAudit(UserName);
return u;
}
Vous ne pouvez pas créer une instance d'une interface
Correct. Vous créez une instance d'objet implémentant une interface:
IAuditable myUser = new User();
Aucun endroit dans le code ne définit-il quel IAudit s'applique à quel IAuditable
Vous ne pouvez pas le faire directement avec une seule interface. Vous devrez repenser votre conception.
Vous pouvez utiliser un type générique ouvert dans l'interface et l'implémenter avec des types fermés:
public interface IAudit<T> {
DateTime DateCreated { get; set; }
}
public class UserAudit : IAudit<User> {
public string UserName { get; set; }
public DateTime DateCreated { get; set; }
public UserAdit(User user) {
UserName = user.UserName;
}
}
Je ne peux pas spécifier que l'interface IAudit doit avoir un constructeur qui prend un IAuditable
Correct, vous ne pouvez pas. Voir ici . Vous devez créer un tel constructeur sur les implémenteurs.
Une façon serait d'utiliser des génériques.
Une fois que vous avez un type T qui implémente I interface et a un constructeur public, sans paramètre, vous pouvez créer une instance de T:
public void Create<T> where T : IAudit, new()
{
T instance = new T();
// TODO: Your logic using such T instance of IAudit implementation
}
Je ne connais pas votre architecture de code ni votre objectif, mais vous pouvez créer une méthode fabrique comme celle ci-dessus pour créer des instances d'objets IAudit.
Évidemment, vous ne pouvez pas créer une instance d'interface, mais si vous essayez réellement de créer une instance de la classe passée, vous pouvez faire ceci:
IAuditable j = ((IAuditable)Activator.CreateInstance(myObject.GetType()));
Vous devez savoir quelle classe concrète construire et dans votre exemple, la seule option possible est myObject.
Vous pouvez également rechercher un élément appelé «Injection de dépendance», qui vous permet de spécifier le type de classe concrète à «injecter» dans des paramètres qui appellent des interfaces dans des constructeurs ou des champs. Je ne suis pas sûr que votre conception totale, donc cela pourrait être applicable. Dans Dependancy Injection, vous pouvez indiquer dans votre code que IAuditables doit être créé à l'aide de UserAudit, bien qu'il y ait un peu plus de câblage que de simplement appeler "nouveau IAuditable".
Si vous devez créer une instance pour une interface, vous pouvez créer une classe publique nommée FactoryClass () contenant la méthode Interfaces. vous pouvez utiliser le code suivant:
public class FactoryClass //FactoryClass with Interface named "IINterface2"
{
public IInterface2 sample_display() //sample_display() is a instance method for Interface
{
IInterface2 inter_object = null; //assigning NULL for the interface object
inter_object = new Class1(); //initialising the interface object to the class1()
return inter_object; //returning the interface object
}
}
Dans la classe Main (), ajoutez le code suivant:
IInterface2 newinter; //creating object for interface in class main()
FactoryClass factoryobj=new FactoryClass(); // creating object for factoryclass
Dans le constructeur, ajoutez ce qui suit:
newinter=factoryobj.sample_display() // initialisingg the interface object with the instance method of factoryobj of FACTORY CLASS.
vous pouvez appeler la fonction en utilisant le code suivant:
newinter.display() //display() is the method in the interface.
Nous ne pouvons pas créer d'instance d'aucune interface .Interface peut contenir une adresse mémoire qui hérite ou implémente cette interface E.g
interface IInterface
{
void GetData();
}
public class SomeClass : IInterface
{
public void GetData()
{
//do something
}
}
class Program
{
static void Main(string[] args)
{
IInterface Iface = new SomeClass();
Iface.GetData();
ReadLine();
}
}