How to share c# source between Unity projects? - c#

We have two projects underway and want to share some classes between them. The shared source must be in a single location so when a programmer on Project1 updates the code those changes are immediately seen in Project2.
The important part is that we do not want to maintain multiple copies of the same code. i think we would agree that its simply bad practise to do so.
The only option appears to be putting the code in a class library and load it as a plugin into each project. But I don't believe this works when referencing Unity types like GameObject or transform.
In C/C++ land we could put the source in a directory and include it into any solution we wanted - doesn't seem to be so easy in Unity-land. Is their a better way to share code between unity projects?
EDIT: All projects, including the shared code, are already under source control. This is not a Source Control question, its a framework issue. (And obviously I need to write better questions!)
Lets say the directory structure looks like this...
C:\
Project1\
Assets\
CodeForProject1\
StandardAssets\
Library\
C:\
Project2\
Assets\
CodeForProject2\
Resources\
Library\
D:\
UsefulCode\
PlayerClass\
WeaponsClass\
DataAccessClass\
Can Unity reference code from other projects? Can Unity reference code outside of its own Assets folder? If so, how?

I understand exactly what you're facing, we faced the same problem here some time ago.
The idea of our shared code is to be sort of a middleware, so it is natural that it will evolve through. Our solution was to create a git module for the shared code. I know you said that it's not a source control question, but at least here in my company, create a dll was not a good solution since we are changing the shared code constantly (we tried soft-links too, but it was very painful to maintain in all machines).
Here we created two projects: one for the middleware and another just for the tests. The last one have only the gitmodule to the middleware and a bunch of unit tests. We did it to ensure that there is no dependency to other projects. Both are in the source control. So when someone wants to implement a new feature inside the middleware, he/she make it inside the tests project, and when it's done commits to both projects.
Oh! And you can make a dll with Unity types and use them normally.

Related

c# interface references

Hello everyone
Currently I have the following reference structure:
DSFinalProject have reference of "DAL" project and "DataStructure" project.
DataStructure have reference of the DAL project as well…
Now I want that DSFinalProject won't have reference to the DAL layer but will be able to use interfaces from that class.
Is there any way to "tunnel" the interfaces that are in the DAL project to DSFinalProject without actually making references between them?
Maybe using the DataStructure project? Or anything else?
Thanks in advance for any help :)
The easiest way is to put them in DataStructure, which isn't too bad since anything that references the interfaces will need to reference DataStructure as well.
My vote would be to put them there until you run into a scenario when you need to have the interfaces in a separate assembly.
I don't know of any way to reference interfaces (or anything else) inside the DAL project from DSFinalProject without having a reference to the project (or assembly).
You can move them to another project if you think it makes the dependencies cleaner - if you put the interfaces in the DataStructure project - you'd run into a circular reference where it needs DAL and DAL needs it.
I don't believe that there is anyway to so what you ask. If you think about what happens when you serialise objects, you still need the assembly to provide the low level structure of how the fields are laid out inside the stream of data. It needs the code in the interface to say that the first 4 bytes are a double, etc.
So the only to do this is to move your interfaces into a new interfaces.dll which can be referenced by everything. You will see this pattern repeated in many examples including the EnterpriseLibrary.
However...
you are making a classic mistake. Why are you splitting your code into so many projects? Projects really should be thought of as the run time packaging of our code, not a desing time segregation mechanism. By splitting into so many assemblies, you do three things.
You slow your build system down, as the compiler does more work fetching the other assemblies.
You slow down Visual Studio as it works harder to load up all the projects and keep the references between them. I once worked on a solution with 140 projects that took 15 minutes just to open (but I always got my morning coffee).
You slow down the run time performance as DotNet has to search around for another 4k dll (thats the minimum, even for just one line of code). Try looking at the fusion logs or use SysMon to see just how much work is involved in this simple operation.
Take a look at this example Hints on how to optimise code do see what's going to happen as your solutions get more complicated.
Instead of splitting it like this, use namespaces instead, you will still have the seperation, but instead of having to use so many references, you now have control by the using statements inside your classes. You will easily see if you are using a DAL reference in a class designed to be in a DSFinalProject tier. You can just create a folder under the project and add your classes there instead. Get rid of all the projects and still have a properly tiered system.
As your solution grows, wait until you have at least two executables before you start introducing projects, and then consider the run time implications. If you are always going to load up two assemblies, merge them into one (I've seen some open source projects these days that use ilmerge to merge in third party libraries too).

Easiest way to refactor package in C# or Java?

I'm very annoyed by C# or Java refactoring of namespaces or packages. If you referenced in many classes a class in a common package used in many independent projects and if you decide to just move that package as a package child of the current parent package you have to modify all clients just because you cannot use generic imports like this
import mypackage.*
which would allow refactoring without impacting clients.
So how do you manage to do refactoring when impact can be so big for such a small change ?
What if it's client's code not under my control am I stuck ?
Use an IDE with support for refactoring. If you move a java file in Eclipse, all references are updated. Same for rename, package name changes, etc. Very handy.
It sounds like your asking about packages that are compiled and deployed to other projects as for instance, a jar file. This is one reason why getting your API as correct as possible is so important.
How to Design a Good API and Why it Matters
I think that you could deprecate the existing structure and modify each class to be a wrapper or facade to the new refactored class. This might give you flexibility to continue improving the new structure while slowing migrating projects that use the old code.
imagine someone doing an import like import com.* and if it was like what you wanted it to be, it will load anything and everything in a com package which means zillions of classes are going to be imported, and then you will complain about why it is so slow, why it requires too much memory......
In your case, if you use a IDE, that will take care of most of the work and will be very easy but you will still need to deploy new executables to your clients as well if your application architecture requires.

Managing Code Assets

I have written quite a bit of code of the past few years. I've been using the Visual Studio Development Environment for my C# code, but I wouldn't call myself an advanced user of Visual Studio. I can create projects, create source code, and build/debug the project. I don't use many of the advanced features of the IDE, so perhaps there is a simple way to do what I'd like.
My code is often reused - especially thing like filter tools, custom controls (plots/etc) and some communications code (COM/USB/etc). Every time I create a new project, I end up importing a lot of code that I'll need. This code is copied to the new project directory. If I end up editing that code in some way, I then need to update all of the other versions of that file in my others projects. I'm always having to verify that the code that I am importing is the 'latest and greatest'.
I know it is possible to add code to your project by link, and then you'll update the source file, but I'm curious if there is a better way. My example of a 'better way' is the Allegro Lisp compiler. When you start up Allegro, all of your code is loaded into Allegro, and is instantly available. Then you can start hacking around on anything you'd like, and have access to all of your previous code. When you edit something, and compile it, it is instantly usable in the rest of your projects as well. (Usually even if the program is open!) Perhaps this is something fairly unique to Allegro Lisp?
Are there any ways to do something like this in C#? I'd like to still be able to keep separate projects, but I'd like to share source between them and not have to worry about versions getting out of sync. What does everyone else do when they would like to recycle code?
Thanks,
Giawa
Take some time, work through the code and create different projects, for the likes of filters, plots. Give meaningful namespaces to these assemblies, put the code under source control, use external references to these repos in the source control of your main project, or only import the generated assemblies.
Copying code will lead to errors due to not correcting an error in one place, but correcting it another. Use source control, it's gold.

SSIS and re-using C#

I'm a newbie to SSIS / C# (I'm generally a Java developer) so apologies if this is a really stupid question.
Essentially the problem is this: I have two Data Flow tasks which load data up and export them to a legacy flat file format. The formatting is done by a Script Task (C#).
What I'd like to do is share some common code between the two. e.g. I could create a common base class and then extend it for my two different script tasks.
However it seems that SSIS doesn't really make provision for this.
Does anyone know if there is a way of accomplishing what I want to do?
You're correct that there is not a straightforward way to do this directly from SSIS.
In a recent project, we took two different approaches, which both worked fairly well depending on what you need to do:
Create a utility class (as a simple class library) and reference it from your script tasks. This is done pretty much the same as any other sort of reference. If you use .NET 3.5, remember that you'll have to update the version manually in the script tasks since SSIS defaults to 2.0. We also found that if we wanted some manner of reusability in the utility assembly (not relying on hardcoded variable names, etc.) then the package still had to have a fairly large amount of "setup" boilerplate to use the utility scripts.
Create a custom data flow component. This is a much more involved process, but ultimately will do the best in terms of avoiding code duplication. Generally, coding the actual data flow is fairly simple and not that much different than a script component, but the various setup code you'll need can tend to make things complicated. There's also not a lot of support in SSIS for when something goes wrong. Led to a lot of detective work on our project.
If you plan on using something a whole lot, and are committed to getting rid of boilerplate code as much as possible, 2 is the preferred option. If it's being used a few places here and there, consider the simple approach of 1.
I am pretty sure it's possible to access .NET assemblies in SSIS scripts. So you could do it this way. See the article "Accessing .NET assemblies with SSIS" on SQL Server Central.
I believe you will have to create an assembly or webservice for this to work.
This does not completely solve your issue but it does help in not having to recreate all the classes every time you need them (I also do not want to deploy referenced assemblies for my current project ). Firstly you need a master copy of your classes, you can copy them from an existing Script Task using the same process below but in reverse.
Open the Editor for the Script Task and on the Property Explorer click on the Project File (the st_[Guid] ), in the Properties window you’ll see the Project Folder location. (This location gets recreated every time you edit the script task)
In explorer, copy your classes to this folder
On the Project Explorer, click on the “Show All Files” icon
Right click on your files and add to Project
Probably way too late to answer this, but you can click on the solution and add a class there. Then when you go into your scripts you can say add existing object and search for that class you created earlier. For me it was located by the solution for the project. Haven't gone through the deployment or anything for this, but at least you can access the class through the individual scripts.

When to create your own dll what should be in it

I as of yet, have not had a need to create a dll in .NET as my programs tend to be distinct from one another (and I haven't programmed for too long). However I am starting to gather a library of regularly used methods now which tend to have copies in lots of my programs (or similar methods that could be made more generic).
As I understand it a dll should be created to share common methods between programs.
So I can put my methods in the dll, what about things like custom dialog boxes and common forms. I currently have a custom error form and a print preview dialog which are used in almost all my programs. Is it good practice to put these in a dll?
"Good practice" in this case really relies on how much code-duplication you're cutting down on. If these dialogues are used throughout a lot of your programs and they take up a lot of code, then yes, it's probably a good idea to move them to a shared space.
But don't be tempted to throw everything in there. You'll find yourself having to override it and by that point you're probably writing more code than you were before. Keep things simple. Keep them generic. Keep them useful.
Before you start, though, be aware that you are creating a dependency tree. If you update your library chances are you'll have to put in some time maintaining your apps that use it... But this is no different from using a third-party lib.
To create a new dll, you just add new project (library) to your solution, and add it as a project reference to your main programme.
It is possible to put anything you want to this project. All dialog boxes, user controls, etc. are just classes, so you can share them as easily as any other class. I think it is good practise to share as much as possible.
Sure why not?
What you're building here is actually a small framework, pretty much like the .Net framework itself. Everything that you think is common between your applications can be put in the assemblies: forms, methods, business logic, exceptions, common data access.
When your framework grows you might want to split up that common DLL. For example if you have common forms in a DLL and you also develop batch applications then they don't need to reference to the DLL containing the WinForms specific classes.
Alternatively you can put the source files for these methods in a common place and just add them as links when you include them in your project/solution.

Categories