Here's the setup I have in a vs2008 solution:
Data layer in a project named MyProject.Data
Web application in a project named MyProject.Web
MyProject.Web has a reference to MyProject.Data
In MyProject.Web I have a class I use called "MySite.Utils"
I want to be able to use MySite.Utils in MyProject.Data but I can't because it would cause a circular reference.
One solution which is NOT possible is creating a third project and moving "MySite.Utils" in there because MySite.Utils actually uses MyProject.Data (thus it needs to reference it and another circular reference would be created)
What's the best/easiest way to fix this?
You need to move MySite.Utils to MyProject.Data by the sound of it
The best fix is to simplify things... for example, is that utility code data utility code, or ui utility code. Perhaps split it into 2 dlls; that might make things simpler.
After that, interfaces are a reasonable option, but you might need some IoC framework to provide the implementations. IoC is the most common way of getting around this type of problem. For example, you declare your ICustomerRepository in a reference assembly; everything references that. Your DAL implements the interface, but the utils project no longer needs to reference the DAL - just the interface assembly. Your DAL can now reference the utils - or it might just know about another interface IDataUtils (better to split it up more meaningfully, of course). The glue here is the IoC container, such as Castle Windsor.
Finally, and don't do this, but even though the IDE doesn't let you, it is possible to create circular references in .NET (via the command line tools); it is legal, but it gets very messy very quickly, and it is hard to repair a broken build. Don't go there!!
Defeat coupling with dependency injection.
Program to an interface.
MySite.Utils shouldn't reference any other project in your solution. Any classes that reference another solution within Utils should be moved into that solution it references.
I believe that the ONLY way to fix this would be to move all the inter-related functionality in one assembly so that there are no circular references. Sorry. :(
Perhaps think about changing the architecture somehow that this is not required?
Sounds like you could benefit (and enjoy!) from reading this...
http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756
Related
I am working on a WPF project using MVVM pattern. In solution, I have viewmodels,models,views and properties.As per requirment, I need to access the same classes(view models, models, properties) from another class library in same project. I do not want to add the reference to the class library as it is an exe file and a heavy component which has got so many classes which i do not require. So, is there any solution for this. How can i access same classes(view model,model,propeties) in a solution from another class library in same project?
Thanks & Regards
You have two choices. First one, is to refactor your exe in order to extract the reusable classes to a separate dll. Then, just add a reference to this new dll.
The other is to use reflection to access the members of the exe, which is the worst option, even worse than simply adding a reference to the big old exe.
I suggest breaking down your solution further in more projects, For example separate projects for Model, View and ViewModel or perhaps breaking down even further and then add reference only to the library you need. That way you are not exposing everything.
The other option is reflection which may be cumbersome to use and make your code ugly.
Scenario
I have a solution on which I have (more than) 2 projects.
The first project has a project reference to the second project. The second project doesn't have a reference to the first project.
Well, in the first project I defined a inheritable class-type on which I would like that some classes from the second project inherits from it.
Problem
Obviouslly, If I want to inherit the type defined in the first project, in the second project I need to add a project reference to the first project to be able see the type and go on.
The problem is that when I try to add the project reference, I get this error message:
Question
Someone could explain me with other simple words (maybe with a code example too in case of code is implied in the error) what is a circular dependency?, and the most important thing: what can I do to solve it? (please read the last prhases of my research before answering).
Research
Is the first time that I hear the term "Circular dependency"; I've read this article from MSDN but I understood nothing.
Anyways I seen many questions of circular dependencys like this, and from what I've seen in that question seems that a circular dependency means that two projects cannot reference between them at the same time, just one of those two projects can reference the other;
and also all the people who answered in that question said things like "Re-design is the solution" or "Circular dependencies are not good practices", however, re-designing in my case will mean define the same type in both projects, which I don't think that could be good practices neither, and of course building an additional assembly/project just to store a single type to reference that assembly in both projects ...is the worst idea I think.
A circular dependency is where Project A depends on something in Project B and project B depends on something in Project A. This means to compile Project A you must first compile Project B, but you can't do that as B requires A to be compiled. This is the problem that circular dependencies cause.
If you introduce a circular dependency to a project that you've already built it can be hard to spot as the standard build options don't remove the existing object files thus enabling you to build A (or B) first. You'll only spot it when you try on a different machine that's never built the solution before or if you do a clean & build.
re-designing in my case will mean define the same type in both projects, which I don't think that could be good practices neither.
In this case you need to create a third project "C" which contains the classes that both A and B depend on so they no longer depend on each other. You might get away with just splitting the classes up so that dependencies can be sorted that way without creating the third project.
What is a dependency?
In order to understand what circular dependency is, it is better to understand what is a dependency and what it means to the compiler.
Let's say you have a project and, in a class, you have the following defined:
Public Class MyClass
'Some code here
Private MyString As String
'Some code there
End Class
When compiling your project, the compiler runs into the String class, which is defined in a DLL file called System. It will then link that DLL to your project, so at run-time, when defining or doing operation on the string, the System.dll will be loaded to perform those.
Now, let's say you have, further in your class, the following definition
'Some code here
Private MyObjet as CustomClass1
'Some code there
And let's say CustomClass1 is defined in another project of yours, named Project2.DLL:
Public Class CustomClass1
'Your custom class code
End Class
So when compiling your first project, the compiler will run into CustomClass1 definition, it knows it lays into Project2.dll and therefore will compile Project2 before, in order to be able to add that reference in your first project.
That's what a dependency is, it's hierarchical, there must be a starting point. Even the String class is dependant on other classes, and at the end, they all rely on bytes or bits to do the job, because that's the only thing a computer can do, play with 1 and 0.
So the circular part
So if you have, in Project2, a reference (a field definition, or something like that) that link to your first project, what happens?
The compiler reads your first project, then runs into CustomClass1
Then it tries to compile Project2, since CustomClass1 is defined there
Then it runs to a class defined in your first project
It tries to compile your first project in order to link it to the second
Then it runs to CustomClass1
Then it tried to compile Project2
I guess you got it...
So at some point the compiler displays an error, saying it cannot compile, as it doesn't understand what you're trying to do...
Yes, computers are that stupid.
How to solve it ?
Solving these kind of issue is sometimes difficult, but the basic idea is to build up a hierarchical structure, put the base class (those which don't need dependencies) together, then build up on them.
Take all the classes that depend on each other and put them together, they form a layer for something you try to do in your application.
Easiest way I know to fix CD is to create a PROJECT-of-Interfaces and have the projects that are involved in the CD to reference the PROJECT-of-interfaces, instead of each other.
Little messy, but it works.
instead of using projects as references use the builded DLL of that project for referencing.. if you do the same in every modules of solution u can solve it.
if u have two projects named as 'main' and 'sub'
then in the main project add DLL of Sub project as refrence file and the same time in Sub project add the DLL of main project as reference..
I've a c# .net WPF application, now i need to register something(basically kernel of NInject IoC pattern) that has been used by the BLL and DAL layer.
I want to know the entry point or something like that for the dll where i could put that code(kernel registration).
For WPF section, i use App.xaml.cs, for WCF section i use Global.asax.cs as they are the entry point of these things. But what about standalone dlls, what is their entry point.
One approach is that, i could add a static class in my dll which fulfil this purpose and from app.xaml.cs i call this method of BLL and register my kernels. But this seems more like a workaround than approach.
Please guide me for something more to the point and logical.
Container configuration is done in the composite root of your application (The point where your code is called the first time). As you already said, in case of WPF this is the App.xaml.cs. Here you register the components of ALL layers. Preferably you have to UI code in another assembly than the App.xaml. This way the creation of the spplication is completely separated from the execution of the code.
I suggest to read Mark Seemans book where this is described in detail.
C# doesn't allow to run code on assembly loading, and static class constructors are lazily executed on first access to the class. However the CLR supports a static "assembly constructor", so to speak, which is executed when the assembly is first loaded. Mind you, references are still loaded lazily unless you put in special attributes to mark a referenced assembly to be loaded eagerly.
If you want you could put a static constructor into the assembly module through ildasm/ilasm. You could probably make some scripts to automate this on build.
I didn't do this myself yet, so I can't give any examples. Though if you consider doing it I can maybe dig up some links.
It almost sounds like your wanting a "plug-in" model where the app can dynamically discover components that are available. If so, then MEF might be a better option.
MEF seems to work well for cases where the app might not know about all it's dependencies ahead of time. Dependency injection, on the other hand, assumes that your app is fairly knowledgeable about these dependencies ahead of time.
I don't know if this is what you're after, but it might be worth a look.
I wrote some classes that I use with many different projects.
For example, I use Library.Controls.FlatButton.cs almost in every project.
The problem is when I add this as an "existing item"; the class gets created/copied in my soultion folder everytime. And each time I edit/update the contents of that class, I have to update all the Library.Controls.FlatButton.cs files in every project folder.
I need to be able to edit a single source of FlatButton class and when I compile/build a project (that uses the class file) gets updated to the new version of that class.
Question 1: Is there a way to do this?
I know that I can gather all these classes in a library project (Library.Controls) and add it to each application solution as a dependency.
Question 2: Is this the only way to work from a single source of common library files? And if I do; will all the classes in the Library.Controls namespace get compiled with every application, even if I've only used this FlatButton class in the project?
Hope this is clear for you..
thanks
I'd rather go with the approach of the shared library and add them as references to your client project.
If you don't want to do this. You could add the file as "Link". In Add existing item, select Add as Link instead.
Yes, a class library is the way to go and yes, since the whole class library will be referenced from your applications, all the classes will be available to it.
However, the fact that all the classes are available is not a bad thing, since they're in a separate class library it won't make your applications harder to understand (since the amount of code in those applications will stay the same), it might just be that you use up a little bit more hard drive space, though if you really worry about that you could put the class library in the GAC so that all apps reference the same copy of the library, though you'd better research this first to make sure that it's suitable for you.
Alternative way is to add FlatButton.cs file "As Link":
I have an ecomm application in Project#1.
I have a payment gateway implementation in Project#2 that references Project#1. It references interfaces so that the gateway is implemented to a contract.
Now I need to actually use the implementation from Project#2 in Project#1.
There is a circular dependency so it isnt' working as it is.
What shall I do? Should I break the interfaces into their own project? That seems like the easiest approach.
The point is that if I need to create another implementation of a gateway, it can easily be incorporated into Project#1.
Putting interfaces in a separate library is often a good idea. It also ensures that you can vary and deploy concrete implementations independently of each other.
As a general rule of thumb, when I design, I start by putting the interfaces together with their consumers, and I then move them to a separate library if the need arises.
As far as I understand your description, you have consumers in each library, so moving them sounds like the correct approach.
If you find that these interfaces are sufficiently unrelated, you may even want to consider putting them in two different libraries.
Yes. You should put the interfaces that the plugins should implement (along with any potential common helper code) in a separate assembly.
Yes, break your interfaces into another project and reference that project from both. This way, both are dependent upon an abstraction.
This is a dupe of your other question, but it at least has more detail.
If Project 2 is a plugin to Project 1, then Project 1 should not have any dependencies on Project 2, under any circumstances. Period.
Load Project 2's assembly into Project 1 via reflection/MEF/etc.