C# best way to share project but expose only methods required - c#

I have a Visual Studio Solution with two Web API projects and some shared or common projects.
WebAPI_1 (Big API)
WebAPI_2 (Very small API)
Data Respository
SecurityRepository.cs
Data Interface
ISecurityRepository.cs
Services
SecurityService.cs
Utility
WebAPI_2 project will use some methods from SecurityService.cs but only 5 from almost 50.
SecurityService.cs inside calls the methods using Dependency Injection from ISecurityRepository
Because when referencing a project will expose the complete DLL, is there a way that WebAPI_2 only sees the 5 methods that is going to use but there is no way to see the other 45 methods?
Also because Dependency Injection is used I was thinking maybe on creating other Interface with only the methods that WebAPI_2 SecurityService is going to use. But again the problem is that the whole Data.Interface project will be referenced.
I don't want to end having 2 projects of each just because of this.
Update: Don't know if InternalsVisibleTo could be used in this scenario but at the method level.

If you have source code for each of the API's, group them into a single assembly, marking everything as internal, and create a public API to expose it to external consumers.
I recommend using a Dot Net Obfuscation tool. C# sources are too easy to reverse engineer. If theft is an issue, program in C or C++ and expose a managed wrapper to C#. Beyond that, use a hardware encryption device to run/decrypt the program on the fly.

Related

How to hide C# class from custom IL Inspector?

I am currently working with a piece of software known as Kofax TotalAgility or KTA for short.
This is Business Process Automation Software, which I have the "pleasure" of expanding with custom .net libraries.
I have been creating a MS Graph library to perform actions with the MS Graph API. The API works great and I am quite pleased with how it turned out.
However due to the way KTA is accessing methods in classes I have used "Data classes" (dont know if that is the right word) to use as input parameters for my methods. To be clear these methods have no functionality other than to store data for methods to use, the reason I am doing this, is because of the way it is structured in the KTA class inspector (I am assuming that KTA uses the IL Code from my library to create a list of classes and methods).
This is what I am expecting the user is shown when they are using my methods. As you can see by using classes as input parameters I get this nice hierarchical structure.
By using classes as input parameters another issue occurs which is that my "Data Classes" are show in the list of classes, which produces alot of unnecessary clutter.
Is there a way to hide these classes from the inspector? I get that it might be an internal KTA issue, which of course would mean I am not asking in the right place, and it is an internal Kofax issue.
However if there is some C# or .NET way of doing this, that would be preferable.
There are a number of different terms for the data/parameter classes that you mention, such as DTO (data transfer objects), POCO (plain old C# objects), or the one that you can see in the KTA product dlls: model classes.
There is not a direct way to hide public classes from KTA. However, when you use the KTA API via the TotalAgility.Sdk.dll, you notice that you don’t see all of the parameter classes mixed in with the list of the classes that hold the SDK functions. The reason is just that these objects are in a separate referenced assembly: Agility.Sdk.Model.dll. When you are configuring a .NET activity/action in KTA, it will only list the classes directly in the assembly that you specify, not referenced assemblies.
If you are using local assembly references in KTA, then this should work because you can just have your referenced assembly in the same folder as your main dll. However if you are ILMerging into a single dll to can add it to the .NET assembly store, then this approach won’t work.
When ILMerged together, the best you can do is to have your parameter classes grouped in a namespace that helps make it clear. What I do is have a main project with just one class that acts as a wrapper for any functions I want to expose. Then use ILMerge with the internalize option, which changes visibility to internal for any types not in the primary assembly. To allow the model classes to still be public, I keep them in a specific namespace and add that namespace to the exclude list for the internalize command. See Internalizing Assemblies with ILMerge for more detail.
Keep in mind that anyone seeing this list is configuring a function call with your dll. Even if they are not a skilled developer, they should at least have some competence for this type of task (hopefully). So even if the list shows a bunch of model classes, it shouldn’t be too hard to follow instructions if you tell them which class is to be used.

Incorporating a log4net wrapper class in a C#.NET project following MVVM

I've created a log4net wrapper class for my project team to use so we can all log from the same instance of log4net in our project. We're unsure what section this could come under i.e. Controller, one suggestion was to create a separate folder altogether for "Helper" classes.
Is there an industry standard to follow for this that we could use?
I can't speak to an 'industry standard' but for our application, putting the logging at the lowest level has worked best for us. We created our own class that wraps the 3rd party functionality in a one of our libraries referenced by nearly all others. Then we implemented our own methods to simplify and standardize logging in our app. This approach makes it possible to use logging anywhere without significant project changes. You'd just have to add static method calls where you need to log something.
No there's no industrial standard for such things. Nevertheless, instead of creating another wrapper for log4net consider using the existing one. Then simply register it in the DI of your choice and inject it via constructor.

Ensure only one class can access a reference dll?

I have a project where I want only one class to have access to a dll. I would be content with hiding the dll from intellisense, but still having access to it if that is an option. Either way, I want only one class to use the dll and for it not to be seen and/or accessible otherwise.
I'm using C# in visual studios.
Simply said: You can't do that (but keep reading).
Basically, a DLL (From the .NET perspective) is a bunch of code and config files. No more than that. So, given that you'll need to make public those classes in order to be used from another ones outside that assembly then you can not.
What you can do (I ended up doing this a few years ago) is to use some kind of reflection to determine which class (and namespace) is trying to access your assembly and only permit the proper one.
Other way is to implement a key negotiation between your DLL and the permitted assembly. You'll need to implement those manually, as far as I know.
Anyway, keep in mind there's always a way to bypass this kind of protection by disassembling and modifying your code. So, at least, don't forget to obfuscate the file. Anyway, this will just make it a little more painful, but still possible.
An alternate approach, if you goal is to stop people using the functionality of the dll by accident is to push your wrapper class into an intermediary assembly. Your project then references that intermediary project, rather than the underlying dll which effectively hides it. So your project structure would change to something like this:
Main Project -> references API Wrapper Project -> references API DLL
For this to work, your wrapper project needs to make sure that it doesn't accidentally expose any of the API DLL classes through its public interface.
Obviously this doesn't stop your developers from going in and adding a reference to the API DLL so that they can use the library directly, but if the goal is to stop accidental access to the API DLL classes because intellisense has helped the developer out a bit too much then it might be a viable option.

how to have only one project for different versions of .NET?

Well, I have a project, and by the moment I am using .NET 4.0, because I would like that this application is compatible with windows XP, because EF 5.0 is only for windows 7 and upper.
However, I would like to implement some parts of the application with the features of .NET 4.5, such as EF 5.0.
So for my database access I have a reposotry class that now use EF 4.0, this is a independent dll, so I can create other repository dll that use EF 5, and in my project import both dlls, then I can instantiate the correct repository according to the version of EF 5.0 that I can use. This is a paramater in the config file. is this the best way?
I ask this because I don't know where I must declare my interface. because my repository classes need to implement this interface, but then this tie my dlls to my application, but I need to use this repositories in two different applications, so I want to implement once, and use in many applications. I want independent dlls, because now are two applications, but in the future, can be more.
The reason to want to use an interface in the application that uses the repositories is because I would like to instantiate at runtime the correct repository, according to the config file settings. So in the fututre I can implement new repositories and there is no needed to change the code.
EDIT1: I read about multi targeting, but if in my project I use features for example of .NET 4.0 and I want to complie for 3.5, I get an error because this feature does not exist in 3.5. That's correct. Then the only way is to mantain two different projects? It would be a double work.
Thanks.
Daimroc.
So for my database access I have a reposotry class that now use EF
4.0, this is a independent dll, so I can create other repository dll that use EF 5, and in my project import both dlls, then I can
instantiate the correct repository according to the version of EF 5.0
that I can use. This is a paramater in the config file. is this the
best way?
You can go this route and I don't really see an issue with it unless you think that this could cause maintenance/development headaches in the future. There are a couple of other things that you can look into doing. I think both are completely valid and probably just personal opinion/preference.
Modules You can go a modular route where your repository DLLs are potentially loaded dynamically. Look into Microsoft's Unity library. This should allow you to create an IModule in each of your repository DLLs that will set up your application as needed. Then just create a UnityBootstrapper class to tell it how to find your modules (manually add them, look in a directory, etc.). This should allow you to hot swap your repository DLLs and not have to worry about setting a config file if you don't want to.
Preprocessor Directives With preprocessor directives you get to define how your code will compile. Depending on how you have your classes structured this may be something fairly simple to set up or a complete nightmare that makes you want to abstract and refactor your classes. This question: Detect target framework version at compile time has an answer for handling different compile results depending on the target framework. Personally though, I like the modular route.
I ask this because I don't know where I must declare my interface.
because my repository classes need to implement this interface, but
then this tie my dlls to my application, but I need to use this
repositories in two different applications, so I want to implement
once, and use in many applications. I want independent dlls, because
now are two applications, but in the future, can be more.
The reason to want to use an interface in the application that uses
the repositories is because I would like to instantiate at runtime the
correct repository, according to the config file settings. So in the
fututre I can implement new repositories and there is no needed to
change the code.
Sounds like you need to create another library that is used to communicate between your UI and your Repository libraries. This can be a little tricky and overwhelming to set up just right. Basically you want your gateway DLL to house the interfaces and business objects. Your Application would reference this DLL and this DLL would reference your repositories.
Depending on your needs you may actually need to set up another intermediary DLL that would actually just house your interfaces and most basic utility classes. This would allow you to have your EF objects implement the same interface that your application is using without the need for your gateway DLL having to map your business objects and EF objects back and forth.
EDIT1: I read about multi targeting, but if in my project I use
features for example of .NET 4.0 and I want to complie for 3.5, I get
an error because this feature does not exist in 3.5. That's correct.
Then the only way is to mantain two different projects? It would be a
double work.
I believe you can get around this by using the Preprocessor Directives I mentioned above. Below is just an example of making a method handle work differently depending on if the framework is .NET 2.0; it's just an example and not tested. The DefineConstants will need to be set up, but this should allow you to handle 1 project for multiple framework targets while also being able to use newer .NET features as they are released.
public Person FindPersonByName(List<Person> people, string name)
{
#if DOTNET_20
foreach(Person person in people)
{
if (person.Name == name)
return person;
}
return null;
#else
return people.FirstOrDefault(p => p.Name == name);
#endif
}
I hope this was helpful and the best of luck in finding the right solution.

What is an easily maintainable way to share a common .net class library over many corporate asp.net mvc 3 web applications?

I've been struggling to do this in a way that fulfills all of my requirements.
Here is what we have in our library:
Base classes for controllers and services
Business objects (stores, departments, etc)
Common Partial Views (Login, Error, etc)
Base class for HttpApplication
General common code (read an INI file, create a db conn, etc)
The one requirement that has been giving me trouble is as follows:
Lives in one place on a server. (i.e. copy local = false)
This breaks because:
The DLL containing the HttpApplication class must be in the same directory as the web apps dll to launch. I haven't found a way around that. I'm ok with duplicating this code in every app, but would rather not.
The shared views don't like to work if I use Assembly.LoadFrom() to load the dll from the shared location. (I've been using this method to precompile my views)
Any namespace shortcuts in web.config break at runtime with compilation errors because the web.config is parsed before the assembly is loaded.
My question to you folks is how do you handle your common code in a similar environment?
The GAC seems to be more trouble than its worth, and we want all of our apps to be using the same code, and not have multiple apps on multiple versions and have to maintain all of that. Are there design patters/best practices that can guide us in this regard?
Also, as a bonus, if you can solve any of the problems above, that would be great, too.
Thanks!
Edit: I guess a question that follows is whether or not we should even have a directory with the common dll(s) on the server, or if they should only be deployed as projects are deployed/updated?
Firstly, you will want to separate out what you're trying to achieve. Don't create 1 library that does everything or you will have a Big Ball of Mud. Don't be afraid to create several maintainable libraries to achieve what you're after. Is there a specific reason it needs to be stored in one location?
For example, several of the items you mention are MVC or web specific. If you have items that can be reused by MVC, create a class library that contains MVC base classes you inherit and reference them in your project. Use the single responsibility principle as much as possible.
Regarding the other items you mentioned, like database connectivity, if it's reusable, abstract it out in a data access class library and reference it. Other simple operations like reading an ini file or creating a file, create another library and abstract it to easy to use methods.
I prefer to copy the library dlls locally. You never know when you will need to make changes to the library, but you don't want all of your projects to stop compiling. When you're ready to implement a new version of the library, copy the dll in and recompile.
Not sure why all the hate towards the gac. It was designed to handle this specific problem. Install your common dlls to the gac and all apps can see them. Need to deploy a new one, just re-install it in one place.

Categories