In the extension method, how to create an object based on an implementation class

In the extension method, how to create an object based on an implementation class. So, in the code below, I wanted to add the AddRelationship extension method, however I'm not sure how in the extension method I can create a Relationship object? those. don't want to associate the extension method with this particular implementation of the relationship

   public static class TopologyExtns
    {

        public static void AddNode<T>(this ITopology<T> topIf, INode<T> node)
        {
            topIf.Nodes.Add(node.Key, node);
        }

        public static INode<T> FindNode<T>(this ITopology<T> topIf, T searchKey)
        {
            return topIf.Nodes[searchKey];
        }

        public static bool AddRelationship<T>(this ITopology<T> topIf, INode<T> parentNode, INode<T> childNode)
        {
            var rel = new RelationshipImp();  // ** How do I create an object from teh implementation 
            // Add nodes to Relationship
            // Add relationships to Nodes
        }
    }


    public interface ITopology<T>
    {
        //List<INode> Nodes { get; set; }
        Dictionary<T, INode<T> > Nodes { get; set; }
    }

    public interface INode<T> 
    {
        // Properties
        List<IRelationship<T>> Relationships { get; set; }
        T Key { get; }
    }

    public interface IRelationship<T>
    {
        // Parameters
        INode<T> Parent { get; set; }
        INode<T> Child { get; set; }
    }


namespace TopologyLibrary_Client
{

    class RelationshipsImp : IRelationship<string>
    {
        public INode<string> Parent { get; set; }
        public INode<string> Child { get; set; }
    }
}

    public class TopologyImp<T> : ITopology<T>
    {
        public Dictionary<T, INode<T>> Nodes { get; set; }
        public TopologyImp()
        {
            Nodes = new Dictionary<T, INode<T>>();
        }

    }

thank

+3
source share
3 answers

You can add an additional parameter of the type representing the implementation class of the relations, specifying the restrictions that should be IRelationship, and have a constructor without parameters:

public static bool AddRelationship<T,R>(this ITopology<T> topIf, INode<T> parentNode, INode<T> childNode) 
    where R : IRelationship, new() {
    var rel = new R();
    // ...
}

, IRelationship ( "R" ):

topology.AddRelationship<string, RelationshipImp>(parentNode, childNode);

EDIT: , : ( ) RelationshipFactory:

class RelationshipFactory<R> 
    where R : IRelationship, new(){
    // no longer an extension method:
    public static bool AddRelationship<T>(ITopology<T> topIf, INode<T> parentNode, INode<T> childNode) {
        var rel = new R();
        // ...
    }
}
+2

ITopology<T> INode<T>, IRelationship<T> factory, . ITopology<T> :

public interface ITopology<T>
{
    IRleationship<T> CreateRelationship(INode<T> parent, INode<T> child);
    Dictionary<T, INode<T> > Nodes { get; set; }
}

AddRelationship<T> :

public static bool AddRelationship<T>(this ITopology<T> topIf, INode<T> parentNode, INode<T> childNode)
{
    var relationship = topIf->CreateRelationship(parentNode, childNode);
    // ...
}

, , .

+1

() . , AddRelationship ? ? , - , node ?

, - :

public interface INode<T> 
{
    // Properties
    INode<T> Parent { get; }
    IEnumerable<INode<T>> Children { get; }
    String Key { get; }

    void AddChild(INode<T> child);
}

public class Node<T> : INode<T>
{
    public Node(String key) : this(key, null) {}
    public Node(String key, INode<T> parent)
    {
        this.Parent = parent;
        this.Children = new List<T>();
        this.Key = key; 
    }

    public virtual INode<T> Parent { get; protected set; }
    public virtual String Key { get; protected set; }
    public virtual List<T> Children { get; protected set; }

    public void AddChild(INode<T> node) 
    {
        this.Children.Add(node);
    }
}

IRelationship. INode .

( OP):

, API , , :

public static bool AddRelationship(this INode<T> node, IRelationship<T> relationship) 
{
    if (node.Relationships == null)
        node.Relationships = new List<T>;

    if (relationship == null) throw new ArgumentNullException("relationship");

    node.Relationships.Add(relationship);
    return true; // I'd make this method void
}

:

INode node = new Node<String>("some key");
INode someParent = new Node<String>("some parent key");
INode someChild = new Node<String>("some child key");

node.AddRelationship(new RelationshipImp(someParent, someChild));

, . , , .

, "node, ", "node "? , . - , ? , , .

, , :

public static bool AddRelationship<T,R>(this ITopology<T> top, INode<T> parent, INode<T> child ) where R : IRelationship, new
{
    IRelationship<T> rel = new R();
    rel.Parent = parent;
    rel.Child = child;
    top.Relationships.Add(rel);
}

:

ITopology<String> top = new TopologyImp<String>;
top.AddRelationship<RelationshipImp>(new NodeImp("parent"), new NodeImp("Child"));
+1

Source: https://habr.com/ru/post/1744740/


All Articles