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

Avoid [ExportTsInterface] attributes with tgconfig.json scanning (feature request) #39

Closed
zarusz opened this issue Dec 7, 2018 · 6 comments

Comments

Projects
None yet
2 participants
@zarusz
Copy link

commented Dec 7, 2018

Hi,

This is a feature request.

It would be nice to avoid having to add [ExportTsInterface] (or [ExportTsClass]) attributes on C# models. Ideally if there would be a way to provide a regex/namespace scanning expression for TypeGen to know what C# models to generate from.

The recently added customTypeMappings in tgconfig.json (#36) brings us even closer to avoid attributes is most cases.

What do you think?

@zarusz zarusz changed the title Replace [ExportTsInterface] attribute with tgconfig.json (feature request) Avoid [ExportTsInterface] attributes with tgconfig.json scanning (feature request) Dec 7, 2018

@jburzynski

This comment has been minimized.

Copy link
Owner

commented Dec 7, 2018

Hey, it's an interesting feature. I'll add it to the 'backlog' and try to integrate it to what already exists. If it doesn't take too much work to implement, it will probably be in the next release. Don't expect the next release to be very soon though - this one may take a little more time to do (probably more than a couple of days). But whenever I manage to do something, I'll let you know in this thread. Cheers!

@jburzynski

This comment has been minimized.

Copy link
Owner

commented Dec 27, 2018

I just released version 2.1.0. I integrated selecting by regex with "generation specs" that I planned to implement for some time now.

So in order to select classes by regex, you would create a "generation spec" file somewhere in your project:

public class MyGenerationSpec : GenerationSpec
{
  public MyGenerationSpec()
  {
    ForAssembly(GetType().Assembly)
      .AddClasses(@"MyProject\.MyNamespace\.(.+)");
  }
}

You can also add regular classes to a generation spec:

public class MyGenerationSpec : GenerationSpec
{
  public MyGenerationSpec()
  {
    AddClass<MyClass>();
    AddInterface<MyInterface>();
  }
}

Then you can select the spec in tgconfig.json:

{
  "generationSpecs": ["MyGenerationSpec"]
}

or you can write it without "GenerationSpec" suffix:

{
  "generationSpecs": ["My"]
}

By default, if you select a generation spec in tgconfig, it will only generate from the spec (and also not read any data from attributes). You can change the behaviour with additional CLI options - you can find them somewhere here.

Also, you can read more about generation spec here in the docs.

Have a happy new year! :)

@zarusz

This comment has been minimized.

Copy link
Author

commented Dec 28, 2018

Hi,

I upgraded to the mentioned version and all worked fine. The feature is exactly what we needed. Thanks for incorporating the idea!

It seems that I can select types using reflection, which is even better than regex ;)

    public class ApiModelsGenerationSpec : GenerationSpec
    {
        public ApiModelsGenerationSpec()
        {
            GetType().Assembly
                .GetTypes()
                .Where(x => x.IsClass && !x.IsAbstract && x.Namespace.StartsWith("MyProject.WebAPI.ApiModels", StringComparison.InvariantCulture))
                .ToList()
                .ForEach(x => AddInterface(x));
            //ForAssembly(GetType().Assembly)
            //    .AddInterfaces(@"MyProject.WebAPI\.ApiModels\.(.+)");
        }
    }

Happy New Year!

@zarusz zarusz closed this Dec 28, 2018

@jburzynski

This comment has been minimized.

Copy link
Owner

commented Dec 28, 2018

Hi,

great! That's a very clever idea - so it seems like you can even do more than I imagined, which is quite interesting :)

Thanks for sharing the idea and I'm glad it works!

@zarusz

This comment has been minimized.

Copy link
Author

commented Jan 15, 2019

Hi,

I just wanted to share my quick finding (maybe it will help someone). The sample from above won't work if you have anonymous types in your assembly (new { Id = 1, Name = ""}). Such types will have no namespace, so need to update the sample to check that Namespace is not null:

    public class ApiModelsGenerationSpec : GenerationSpec
    {
        public ApiModelsGenerationSpec()
        {
            GetType().Assembly
                .GetTypes()
                .Where(x => x.IsClass && !x.IsAbstract && x.Namespace != null && x.Namespace.StartsWith("MyProject.WebAPI.ApiModels", StringComparison.InvariantCulture))
                .ToList()
                .ForEach(x => AddInterface(x));
//            ForAssembly(GetType().Assembly)
//                .AddInterfaces(@"Cosmopolitan.OfferManager.WebAPI\.ApiModels\.(.+)");
        }
    }

jburzynski added a commit that referenced this issue Jan 15, 2019

@jburzynski

This comment has been minimized.

Copy link
Owner

commented Jan 15, 2019

Nice find! I'll also add this filter when generating types from assembly (attribute or GenerationSpec)

-- EDIT
Added in version 2.1.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.