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

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.

Related

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

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.

How can I optionally include an external library?

I have a PCL that I want to contain a bunch of base classes, so I do not have to make them again for each project. Now I am contemplating adding in Facebook, as I will have to reference an external dll each time I want to use my PCL in a project, even if it's a project with only a few screens, because I would have build errors if I don't.
For those saying that's not an issue: I am planning on adding even more external dll's that I don't need every time.
How can I solve this? I want to include the code to use this dll in my PCL, but I don't want to be forced to include the dll each time I use the PCL.
The problem here is that you probably want to use types from the external library in your code, and you can't do that without referencing the library.
A way around this problem is by using reflection, but your code will become much more complex and you wish you didn't.
Another solution is to:
Create an interface for each external dependency in your "common PCL" (ie. ISocialMediaPlatform for the facebook).
Create a new PCL for each external dependency, that references both your "common PCL" and the external library, and has a class that implements one of these interfaces (ie. FacebookSocialMediaPlatform : ISocialMediaPlatform)
This implementation can then reference the external dependency and use its types directly
Inject the implementation of each interface into your "common PCL" using reflection or a Dependency Injection framework
This does add another layer of complexity, but as a side effect it also makes your common PCL code testable.
Finally, the solution I personally would prefer, is to not have a huge "common PCL" at all, but to split it into a few smaller ones that fulfill one specific role.

Provide limited API externally as DLL

If you had to expose functionality externally as a DLL but only a subset of functionality (meaning you can't provide a core DLL as it would expose everything) how is best to do this?
At the moment I can't really see any way of doing it that doesn't involve recreating the parts of the core library in a seperate DLL.
You could use internal along with Friend Assemblies. Your API can be a friend of the core library allowing access to internal members.
See here for more details - http://msdn.microsoft.com/en-us/library/0tke9fxk(v=vs.90).aspx
This would allow you to keep your core objects internalised whilst allowing the API access to them.
Note that you will STILL need to supply the core library. There's no way around this unless you use something to merge the .NET assemblies or you compile the code into your API library.
However I think this is a bad idea and you should keep such entities separate. I don't see why there is an issue shipping more than one library thesedays.
FYI - ILMerge will let you merge .NET assemblies, you can get it from here - http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx
Surely by just creating a new project that wraps the core DLL, exposing only the methods you want exposed, each of which is acting more or less as a "pass-through" to the "Same" method in the core?
So if you core is called Core :)
it might have:
public int Foo()
{
//blah
}
public int Bar()
{
/blah
}
and if you want to only expose Foo, then you create a new project which references Core, and looks like this:
using Core;
public class MyApi
{
private Core _coreInstance.... //some way of reaching Core, in other words
public int Foo()
{
return _coreInstance.Foo();
}
}
An advantage of creating a separate assembly here is that you are then treating your core functionality as one concept, and the exposure of it publicly (to a particular purpose or audience) as another. You may very well want to expose "publicly" different functionality at a later stage, but to a different audience - you now have 2 different public APIs required: therefore any notion of what was "public" in your core assembly is now potentially ambiguous.
I think it depends on the aims you follow in hiding the core libraries.
If you don't want to allow your customers to call the code, for example if that may break usage scenarios of your libraries, or may cause undesirable behavior, or whatever to prevent CALLING the code, you can make the protected classes internal, and use InternalsVisibleToAttribute to include the Facade assembly. I would even use one more build configuration if I still needed core classes to be visible in my applications:
#if PUBLIC_BUILD
internal
#else
public
#endif
class ProtectedCoreClass
But of course if you have too many classes, some script should be prepared to change the existing classes, and Visual Studio's new class template should be modified.
But another case is if you want to prevent the source code from being WATCHED by your customers in order to hide some super unique algorithms or something. Then you should look into some code obfuscator. But there is absolutely no way to 100% guarantee the code from being decompiled and analyzed. It's only about the price crackers or competitors pay for it.
But if HIDING the source code is still extremly important, you should probably just host your code on your servers (to make sure the code is physically inaccessible) or in the cloud, and provide a WCF or a web service your exposing assembly will call.

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.

dll custom business logic

I've a project where some business logic is separated to an DLL project, this DLL contains the business logic for this software for a specific customer.
Now I've a problem after another client with different rules want to implement the software, I need someway that the application load the appropriate dll according to the client using the software, considering that this dll contains same function names but different bodies.
I'm using c# 3.5, is there a way to do so ??
Yes, you certainly can. You can branch the project, alter the implementation of the classes, keep the signatures of all the classes and class members the same, recompile, and your business logic will behave as you wish.
But, this is not good. You will have two different branches, with different implementations, for which you will have to keep the signatures in synch forever. And then you'll have another client, and another. This will be a nightmare that never ends.
Is is possible that the differing functionality can be separated out? You can:
put configuration in the database or configuration files (probably XML). A lot of your app should work based on tables or config files, for this reason.
you can implement plug-ins and providers for places where the code needs to be different.
kindof oldschool, but you can implement plug-and-play functionality using the part of CodeDom that compiles code (ignore the part about graphing out code). You can then put functionality in easily edited text files.
take a look at the Managed Extensibility Framework, built for just this type of thing.
Code the business Logic against an Interface - IBusinessLogic.
You can keep both business logics in the same assembly, and use config based dependency injection to specify which business logic is used during the deployment to the customer.
If I understood your problem correctly than you are looking for business logic customization. You can achieve it through several ways. one of them I am describing here.
Create a folder on your application directory for customization DLLs. Create all your business objects through a wrapper. which will 1st check on customization dll for appropriate Class before any business object by using reflection else it will create business logic from regular class. hope this will help.

Categories