Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cyclic types support in DynamicClassFactory #256

Closed
matt-psaltis opened this issue Feb 28, 2019 · 4 comments
Closed

Cyclic types support in DynamicClassFactory #256

matt-psaltis opened this issue Feb 28, 2019 · 4 comments
Labels

Comments

@matt-psaltis
Copy link

matt-psaltis commented Feb 28, 2019

To model many-to-many relationships, I would like to submit a PR which introduces:

  • DynamicClassDefinition. Allows for customisable namespaces, names and base classes
  • A DynamicLateBoundProperty. This is similar to DynamicProperty however it allows multiple DynamicClassDefinition objects to be constructed simultaneously. This allows the Clr Types to be built with cyclic properties.

Is this something that you would be open to?

Example models:

public class Post
{
	public int PostId { get; set; }
	public string Title { get; set; }
	public string Content { get; set; }

	public List<PostTag> PostTags { get; set; }
}

public class Tag
{
	public string TagId { get; set; }

	public List<PostTag> PostTags { get; set; }
}

public class PostTag
{
	public int PostId { get; set; }
	public Post Post { get; set; }

	public string TagId { get; set; }
	public Tag Tag { get; set; }
}

Example signatures:

public class DynamicLateBoundProperty : DynamicPropertyBase
{
	public DynamicLateBoundProperty(string name, Func<DynamicClassDefinition> definition);

	public DynamicLateBoundProperty(string name, Func<Type> typeResolver);
}

public class DynamicClassDefinition
{
	public DynamicClassDefinition([NotNull] List<DynamicPropertyBase> properties, string @namespace = null, string name = null, Type baseType = null, bool createParameterCtor = true);
}

Usage:

var @namespace="Test.Namespace1";
var postTagDefinition = new DynamicClassDefinition(postTagProps, @namespace, "PostTag");
var postDefinition = new DynamicClassDefinition(postProps, @namespace, "Post");
var tagDefinition = new DynamicClassDefinition(tagProps, @namespace, "Tag");

postTagProps.AddRange(new List<DynamicPropertyBase>
{
	new DynamicProperty("PostTagId", typeof(long)),
	new DynamicProperty("PostId", typeof(long)),
	new DynamicProperty("TagId", typeof(long)),
	new DynamicLateBoundProperty("Post", () => postDefinition),
	new DynamicLateBoundProperty("Tag", () => tagDefinition)
});

postProps.AddRange(new List<DynamicPropertyBase>
{
	new DynamicProperty("PostId", typeof(long)),
	new DynamicProperty("Title", typeof(string)),
	new DynamicLateBoundProperty("PostTags",
		() => typeof(ICollection<>).MakeGenericType(postTagDefinition.ResolveType()))
});

tagProps.AddRange(new List<DynamicPropertyBase>
{
	new DynamicProperty("TagId", typeof(long)),
	new DynamicProperty("Name", typeof(string)),
	new DynamicLateBoundProperty("PostTags",
		() => typeof(ICollection<>).MakeGenericType(postTagDefinition.ResolveType()))
});

DynamicClassFactory.CreateTypes(new[] {postTagDefinition, postDefinition, tagDefinition});
@StefH
Copy link
Collaborator

StefH commented Mar 3, 2019

How would this be used in a real scenario?

@matt-psaltis
Copy link
Author

In my specific use case, its a runtime generated dynamic model, driven by user configuration so specific scenarios are more generalised into their base structure.

We have two such scenarios:

  1. Model many to many relationships using two one to many relationships through the lookup entity/relationship in the middle. An example given above in the Post->PostTag->Tag example.
  2. Parent/Child POCO objects where the Parent object has a collection-of-children property and the children have a property to access their parent.

As DynamicClassFactory stands at present, I cannot construct types of this nature.

Does that help at all to clarify?

@StefH
Copy link
Collaborator

StefH commented Mar 16, 2019

You can start a PR, just make sure unit tests are also created.

@StefH
Copy link
Collaborator

StefH commented Aug 5, 2022

Hello @matt-psaltis, is this still relevant for you? Or can I close this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants