nfplee
nfplee

Reputation: 7987

Creating an Instance of an Interface

I have the following interfaces defined:

public interface IAudit {
    DateTime DateCreated { get; set; }
}

public interface IAuditable {
    IAudit Audit { get; set; }
}

The IAuditable interface says which classes I will have an Audit for. The IAudit interface is the actual Audit for that class. For example say I have the following implementations:

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;
    }
}

Now given an object which is IAuditable (User from above), I'd like to be able to create an intance of IAudit (UserAdit from above) by feeding in the IAuditable object into the constructor. Ideally i'd have something like:

if (myObject is IAuditable) {
    var audit = new IAudit(myObject) { DateCreated = DateTime.UtcNow }; // This would create a UserAudit using the above example
}

However I have a bunch of problems:

I'm sure this is a design pattern many have had before but I can't get my head around it. I'd really appreciate if someone could show me how this can be achieved.

Upvotes: 26

Views: 115406

Answers (6)

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64943

One way would be using generics.

Once you've a T type which implements I interface and has a public, parameterless constructor, you can create an instance of T:

public void Create<T>() where T : IAudit, new()
{
     T instance = new T();
     // TODO: Your logic here to use T instance of IAudit
} 

I don't know your code architecture or goal, but you can create a factory method like one above to create instances of IAudit objects.

Upvotes: 6

user890332
user890332

Reputation: 1361

You can create a static Interface variable outside of the scope and then use it in the code.

static IRequestValidator ir;


static void Main(string[] args)...

Upvotes: 0

Elango
Elango

Reputation: 53

If you are in need to create Instance for an Interface,You can create a public class named FactoryClass() which contains all the Interfaces method. you can use the following code:

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
   }
}

In Main() Class add the following code :

IInterface2 newinter; //creating object for interface in class main()
FactoryClass factoryobj=new FactoryClass();  // creating object for factoryclass

In constructor add the following :

newinter=factoryobj.sample_display() // initialisingg the interface object with the instance method of factoryobj of FACTORY CLASS.

you can call the ffunction by using the following code :

newinter.display() //display() is the method in the interface.

Upvotes: 0

deepee1
deepee1

Reputation: 13216

Obviously you cannot create an instance of an interface, but if you were really trying to create an instance of the passed in class you could do this:

IAuditable j = ((IAuditable)Activator.CreateInstance(myObject.GetType()));

You need to know which concrete class to construct and in your example the only option is myObject.

Alternatively you could research something called 'Dependancy Injection' which allows you to specify which type of concrete class to "inject" into parameters that call out interfaces in constructors, or in fields. I'm not sure your total design, so this might be applicable. In Dependancy Injection you can state in your code IAuditables should be created using UserAudit, although there's a little more wireup than simply calling "new IAuditable"

Upvotes: 7

Oded
Oded

Reputation: 499262

You can't create an instance of an interface

Correct. You create an instance of an object implementing an interface:

IAuditable myUser = new User();

No where in the code does it define which IAudit applies to which IAuditable

You can't do this directly with just one interface. You will need to rethink your design.

You can use a open generic type in the interface and implement it with closed types:

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;
    }
}

I can't specify that the IAudit interface must have a constructor which takes an IAuditable

Correct, you can't. See here. You need to create such a constructor on the implementers.

Upvotes: 19

Tridus
Tridus

Reputation: 5081

No where in the code does it define which IAudit applies to which IAuditable I can't specify that the IAudit interface must have a constructor which takes an IAuditable

You could fix these two by adding a CreateAudit() function to your IAuditable. Then you'd get an IAudit created from the IAuditable. As a bonus if you wanted to store a reference to the IAudit in the IAuditable (or vice-versa) so you can have them related to each other, it's pretty easy to have an implementing class do that. You could also add GetAuditable() to IAudit to get the IAuditable it was created from, for example.

Simple implementation would look like this (on a class implementing IAuditable):

public IAudit CreateAudit()
{
    UserAudit u = new UserAudit(UserName);
    return u;
}

Upvotes: 18

Related Questions