Append generated code to existing file

Posts   
 
    
Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 12-Aug-2015 00:36:46   

I would like to append some code within an existing file. Any pointers how best to do this? I would like to avoid code regions because they are distracting. Instead I would like to parse the code in an existing file and detect the insert point using code.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 12-Aug-2015 08:53:06   

Why not use partial classes? So you extend a class by creating a new partial class file of the same class? Much easier to do and maintain.

Frans Bouma | Lead developer LLBLGen Pro
Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 12-Aug-2015 13:42:12   

When I define a new interface and implementation I want to add an IoC mapping between them to a class that stores all of the mappings for the solution. I'm not sure how partial classes or partial methods would help here as you can't have multiple implementations of a partial method.

Surely then I'd need to have an extra layer of structure to aggregate all the different registrations?

Walaa avatar
Walaa
Support Team
Posts: 14986
Joined: 21-Aug-2005
# Posted on: 12-Aug-2015 22:44:24   

When I define a new interface and implementation I want to add an IoC mapping between them to a class that stores all of the mappings for the solution. I'm not sure how partial classes or partial methods would help here as you can't have multiple implementations of a partial method.

I don't see a contradiction. Partial Classes, let you split a class into more than one physical file. So you can have your own interface implementation on a separate file, than the ones generated by LLBLGen Pro.

Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 13-Aug-2015 13:11:10   
        private void RegisterServices()
        {
            container.RegisterType<ISearchService, SearchService>();
            container.RegisterType<IProfileService, ProfileService>();
            container.RegisterType<IPlaceService, PlaceService>();
        }

This is a method from a class that contains Unity registrations. If I generate a new service interface and corresponding implementation then I want to generate a Unity registration for the new pair too.

I don't see how its possible to use partial classes to aggregate several registrations. The code has to go in a method but methods can only be defined once per class - an implementation of a single method can't be spread across partials.

Incidentally, MVC's T4 controller templates do what I'm looking for. They append a DbSet for an entity to a database context somewhere in the solution, which is specified in the template wizard.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 13-Aug-2015 17:20:52   

You can use partial methods simple_smile (it's a C# /VB.NET feature). What those do is basically you define them in your main class and call them in your code. If you don't add an implementation in the partial method in a partial class, the JIT/compiler will optimize the call away and nothing is done. If you add an implementation it is called at runtime. This is how we added extensibility to e.g. the EF poco classes (see e.g. the OnCreated methods there which are partial)

Frans Bouma | Lead developer LLBLGen Pro
Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 13-Aug-2015 19:39:26   

But you can only have one partial method implementation per class.

I would need one method implementation per Unity registration.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 14-Aug-2015 11:46:44   

You can call to a register service/class which does the registration? The thing is: you need to get a call from inside generated code to a place where you control the result. This can e.g. be a call to a class which through inheritance or calls to services (or using IoC/DI) is composable at runtime. A partial method can make that initial call happen from within the generated code, and after that you can do whatever you want in the code it calls

Frans Bouma | Lead developer LLBLGen Pro
Ian avatar
Ian
User
Posts: 511
Joined: 01-Apr-2005
# Posted on: 14-Aug-2015 14:07:59   

Yes I could start adding more boiler plate but it would be nice to keep the end result simple, and insert an extra line of code somewhere pertinent - as MVC's T4 Controller template does.

I think I will look into using Roslyn.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39760
Joined: 17-Aug-2003
# Posted on: 15-Aug-2015 08:48:15   

Ian wrote:

Yes I could start adding more boiler plate but it would be nice to keep the end result simple, and insert an extra line of code somewhere pertinent - as MVC's T4 Controller template does. I think I will look into using Roslyn.

I don't know how T4's manage to do it, but in any case, it's not really more boilerplate I think, just the call is external to the class, so it's managed externally and easier for automated tools. Using e.g. roslyn also introduces complexity which could be higher than having the call outside the class.

The only facility we have for generating into files which contain additional code is by using code generation regions, but I don't think those cover what you want to achieve (you want the exact opposite: you want to generate into a part of the file, while code generation regions generate in the entire file but contain a safe haven area (the region) for code manually added.

Frans Bouma | Lead developer LLBLGen Pro