Generate internal classes

Posts   
 
    
Posts: 1251
Joined: 10-Mar-2006
# Posted on: 27-Jun-2017 14:31:05   

Using self servicing, 4.2

I am looking to make all the code generated by llblgen be marked as internal. Such as requested in this thread. http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=8894

The reason I want this is common libraries.

I have nuget packages that contain common code. That common code has database access in it. So for example I might have a 'CreateCustomer(...)' method in the common code. That method takes care of properly creating a customer and then that method is used from the project by bringing in the nuget package.

The problem comes in when the calling code can now see

MyCommonNameSpace.CommonCode.Dal.EntityClasses.CustomerEntity

and

MyProjectNameSpace.Dal.EntityClasses.CustomerEntity

this can cause a few problems. Additionally, I have some common projects that are the exclusive way to access the data - no other project needs to import or use the entities it does. However, once they reference the nuget package - then they are available and I don't want them to be. It is like having every class your library uses 'internally' exposed publicly.

I thought a good solution would be to mark everything as internal in the common library dal. I would then use the InternalsVisibleTo attribute (https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute(v=vs.110).aspx) on that DAL such that the common library project could see and use it, but nothing else can.

I have several 'common' projects that could greatly benefit from this. I realize I am on 4.2 and that code is locked, I assume that the latest version has this same issue and was wondering if there is the possibility for an enhancement to allow this type of behavior?

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 28-Jun-2017 08:07:03   

You will need to modify the code generation templates.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 28-Jun-2017 10:06:37   

Marking everything 'internal' will not really mean much: you can access anything through reflection (and as MS has removed 'medium trust' it's not limited to access rights anymore). If you want people not to see things, then the only option is to not give it to them.

With Selfservicing, the entities and the persistence logic are tied together, and although it can be nice to have that, one thing that it brings to the table which isn't great is that if you want to have them separated, you can't.

What you want can be achieved with Adapter though, and some architectural changes. The dbgeneric project gives you the ability to share the entities but not the persistance, and the dbspecific project gives you the ability to write code that accepts an adapter (e.g. through DI or factory lambda) which makes it unusable if you don't have the dbspecific project, so you can share that without giving out other things.

The internals visible attribute has a limitation too if I recall correctly: you have to specify on the Selfservicing project which assemblies are allowed to see the entities, not the other way around. So you have to define that up-front and then share the selfservicing project, which then doesn't bring you what you're after.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1251
Joined: 10-Mar-2006
# Posted on: 28-Jun-2017 13:32:10   

Posted on: 28-Jun-2017 10:06:37 Marking everything 'internal' will not really mean much: you can access anything through reflection (and as MS has removed 'medium trust' it's not limited to access rights anymore). If you want people not to see things, then the only option is to not give it to them.

PERFECT. I am just trying to make it where you cannot accidentally easily pick the wrong using when you type in an entity name.

The internals visible attribute has a limitation too if I recall correctly: you have to specify on the Selfservicing project which assemblies are allowed to see the entities, not the other way around. So you have to define that up-front and then share the selfservicing project, which then doesn't bring you what you're after.

PERFECT. Keep in mind I have a solution - call it 'common code solution'. That solution has two projects - a DAL and an API. I know right up front that the ONLY thing that needs to access the DAL is the API.

What you want can be achieved with Adapter though, and some architectural changes. The dbgeneric project gives you the ability to share the entities but not the persistance,

While I am not an Adapter expert this does not seem like it helps. I DO NOT want to share the entities either.

Imagine having 4 tables that are all related in some way and are all used for some 'subsystem', whatever that might be...say 'managing user rights'. I create an API for 'add user' and 'add authorization' and such. That API accesses the 4 tables via LLBLGen entities. No code anywhere in the system needs to use those entities as it is all behind the API. However, the moment I add through nuget - there they are and if they used any 'common tables' that are used by other systems now we have the same entity listed many times only separated by namespace.

Seems like to me this is a PERFECT case for making everything internal. Keep in mind some other project could use reflection - but why would they - if they really wanted to - they would just add the entity to their DAL and use it directly. I just have numerous libraries that have this exact scenario and I want to hide the DAL. Anytime you have a DAL attached to a shared NuGet package this seems to be really ideal. This is something I have wanted for the last year or two.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 28-Jun-2017 14:07:27   

WayneBrantley wrote:

Posted on: 28-Jun-2017 10:06:37 Marking everything 'internal' will not really mean much: you can access anything through reflection (and as MS has removed 'medium trust' it's not limited to access rights anymore). If you want people not to see things, then the only option is to not give it to them.

PERFECT. I am just trying to make it where you cannot accidentally easily pick the wrong using when you type in an entity name.

The internals visible attribute has a limitation too if I recall correctly: you have to specify on the Selfservicing project which assemblies are allowed to see the entities, not the other way around. So you have to define that up-front and then share the selfservicing project, which then doesn't bring you what you're after.

PERFECT. Keep in mind I have a solution - call it 'common code solution'. That solution has two projects - a DAL and an API. I know right up front that the ONLY thing that needs to access the DAL is the API.

What you want can be achieved with Adapter though, and some architectural changes. The dbgeneric project gives you the ability to share the entities but not the persistance,

While I am not an Adapter expert this does not seem like it helps. I DO NOT want to share the entities either.

Imagine having 4 tables that are all related in some way and are all used for some 'subsystem', whatever that might be...say 'managing user rights'. I create an API for 'add user' and 'add authorization' and such. That API accesses the 4 tables via LLBLGen entities. No code anywhere in the system needs to use those entities as it is all behind the API. However, the moment I add through nuget - there they are and if they used any 'common tables' that are used by other systems now we have the same entity listed many times only separated by namespace.

Ok. The argument for 'types with same name but different in namespace' is something you always will have btw.

IIRC with 2017 15.3 the project system got a bit more sophisticated in visual studio, where indirect referenced assemblies (the one with your dal) aren't needed anymore to be directly referenced by the main project. This is for .net core at the moment, but it's highly likely this is going to be the case for full .net as well.

Seems like to me this is a PERFECT case for making everything internal. Keep in mind some other project could use reflection - but why would they - if they really wanted to - they would just add the entity to their DAL and use it directly. I just have numerous libraries that have this exact scenario and I want to hide the DAL. Anytime you have a DAL attached to a shared NuGet package this seems to be really ideal. This is something I have wanted for the last year or two.

I'll add it to the features to look into in the future.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1251
Joined: 10-Mar-2006
# Posted on: 28-Jun-2017 14:10:43   

IIRC with 2017 15.3 the project system got a bit more sophisticated in visual studio, where indirect referenced assemblies (the one with your dal) aren't needed anymore to be directly referenced by the main project

That is good news I think.

I'll add it to the features to look into in the future.

Thanks for your consideration.