I'm organizing a solution and I need some tips on how to properly arrange the project's components.
Right now I have everything implemented on a single project, but I feel like it makes sense to isolate some of the components on their own projects. The main modules I have are categorzed by folders on the project, and are the Logic module, Database Access module and the Model module. It makes sense to me that these modules should be defined on their own project (maybe as a DLL).
Now, my question comes from the fact that during the application startup, the logic instantiates a configuration class which reads configurations from the app.config file and is known by these modules. Does it make sense to isolate the configuration into it's own project, to prevent the other modules from depending on the logic module? If so, should the configuration class implement from interfaces so that each module only has access to it's relevant configurations?
"The main modules I have are categorzed by folders on the project, and
are the Logic module, Database Access module and the Model module...
the logic instantiates a configuration class which reads
configurations from the app.config file and is known by these
modules."
The picture this paints to me is that you've got a class or classes that either take the configuration class as a constructor parameter, or there's a global/ singleton instance of the configuration class that the other classes make use of.
But the configuration class can read configs, etc. Presumably, the other classes don't need something that can read configs. They just need some values* (that happen for now to be read from a config). Those other classes don't need to go out and ask anybody for those values**; they should just require those values as parameters in their constructors.
This way, those other classes do not need to have any knowledge of the configuration class. Someone just hands them the data that they need. But who?
The answer is the entry point(s)***. Each project in the solution that contains an entry point (console apps, web apps, and test projects) has the responsibility for interfacing with the environment; it knows the context that it wants the rest of the code to run in. So the entry points need to get configuration information by whatever means necessary (e.g. your configuration class or the autogenerated MyEntryPoint.Properties.Settings) and then supply that to the constructors of the other classes they need.
*If each class requires a great deal of configuration information (as your comment below implies), consider either breaking those classes up into something simpler (because needing a lot of configuration may point to an ill-defined responsibility) or grouping the necessary information into DTOs that represent coherent concepts. Those DTOs could then be placed in their own project that can be referenced by both consumers and producers of configuration information.
**This assumes that the values obtained from the configuration class are constant for the lifetime of the objects that would be constructed with them. If not, then instead of taking those values as constructor parameters, you should take an interface (or Func) that you can call for the info you need when you need it. Those interfaces could be defined in an otherwise-empty project which anybody can reference. This sounds like what you're getting at with
"should the configuration class implement from interfaces so that each module only has access to it's relevant configurations?"
When you say
"Does it make sense to isolate the configuration into it's own project, to prevent the other modules from depending on the logic module?"
the answer is yes and no. The Logic module does stuff; doing stuff implies a need for tests; tests want to configure whatever they are testing in whatever way suits the test. So Logic shouldn't be responsible for configuration; it should itself take in information from whoever does the configuration. Rather, configuration is the entry points' job.
***I'm using "entry point" a little loosely here. I'm not talking specifically about the .entrypoint IL directive, but just the first places in your code that can be given control by stuff outside of your control. This includes Main in C# console apps, HttpApplication.Application_Start in web apps, methods recognized as tests by the test runner of your choice, etc.
Related
I'm working with Castle Windsor as an IoC. I'm looking at a bit of code written by a team member and I am trying to figure out what the best practice here would be. Something rings odd to me about the way this was written, but I don't have the experience to say what should be done.
There are two Castle configs (which is my first gripe, but to give a benefit of the doubt, let's say this is okay). Let's say: cfgMain and cfgSub.
There is a main class which is responsible for setting up the application and causing it to run. (It can be a class with a Main() or a Global.asax, doesn't matter). Let's say: MainClass.
There is also a DependentClass.
MainClass instantiates a CastleContainer and installs cfgMain into it, then Resolves DependentClass.
DependentClass creates another CastleContainer and installs cfgSub in it. This is what I have a problem with
It seems like having a hardcoded path to a config inside of a class which itself is created via IoC is a recipe for disaster. It also makes it very hard to unit test.
Call to action: What's the best practice here? Should all the configs be merged? What if there's a reason (read: need) to separate them?
Without the information on why there are two configurations, it is impossible to judge that.
But assuming there is a reason, both classes sound to be parts of the Composite Root, a place near the start of the application that wires up all container dependencies. The main class is the composition root for the first configuration, the dependant class for the second configuration. There is still nothing wrong.
I would say that resolving the dependant class with the first container makes no sense - the composite root is a concrete class and there is no reason to replace it. However, there could be another reason the container is used to instantiate it - dependencies. If the dependant class itself depends on other services, resolving it with the main configuration sounds like the only way to resolve these dependencies.
Ultimately, with no other information, I would say that (with all these assumptions) what you describe could possibly make sense.
However, I strongly recommend to review the need of two separate configurations and two separate composite roots. Sounds overcomplicated.
I'm using the Unity IoC framework and have a Bootstrapper.cs class in my host MVC layer to register all components. However in my architecture I have a 'services' layer below the MVC layer, that too uses DI and there are repository interfaces injected into it (repository interfaces are not used in the MVC layer - it has the services layer Interface injected into its Controllers).
So my question is the following: can I still register the repository interface to it's concrete type in the MVC/UI layer for the entire app, or do I add another reference to Unity and create another Bootstrapper.cs class in my 'services' layer to define Interface types for that that specific layer uses?
Even if the answer is I can register the Interface in the UI layer, I'd still like to know the common practice too. The thing I don't like about registering that type in the MVC/UI layer is I would have to add a reference to the Repository layer just to make the registration, even know it is not used in that layer. It's used in the services layer.
Thanks!
Each application should have its own Composition Root, the place where you configure the application (see this answer for details).
It depends on the context, but generally speaking, if you split your container configuration among the layers you are going to make decisions about the configuration of your layers too close to the layers and you'are likely to lose the general view.
For example, in one of your business logic layers you'are registering a service:
container.RegisterType<ISercice1, MyImplementation1>(new PerThreadLifetime())
But when using that layer in a web application you could decide that a PerSession or PerRequest lifetime would be better lifetimes. This decisions should be in only one place and not spread through the layers.
I turn your question on its head.
If you add a reference to Unity in your class libraries, you would have added dependencies to the framework you are using. That is quite the opposite of what you are trying to achieve.
The only adaptation your classes should need is to support constructors or using public properties - on interfaces. That's it!
So your application entry point should do all the 'bootstrapping'.
Note that a entry point could be different applications, as well as different test projects. They could have different configurations and mocking scenarios.
If your bootstrap.cs gets large, you could split it up into smaller parts for readability reasons. But I reject the idea of classes having any knowledge about the fact that they are being bootstrapped/moqed/injected and by what.
Consider re-use. Your current libraries is using Unity. They may be used in a project using StructureMap. Or why not Ninject.
In short, yes it is possible to keep the configuration at the top of the process or localized to each module. However, all dependencies must be resolved for the entire object graph in the process.
Localizing the configuration by keeping it in each module (assembly) is often a good idea because you are allowing your service layer to take responsibility for its own configuration. My answer to this question, IMHO, is a good practice.
Yes, application should have one composition root at entry point. But it can be a good practice to keep registrations of a classes inside a layer where they are implemented. Then pull these registrations from layers at composition root, registering implementations layer by layer. This is why:
Registration within layer can be redefined in other place, for
example at entry point. Most of IoC libraries work in such a way
that registration done later erases the registration done earlier.
So registration within layer defines just a default behavior which
can be easily overridden.
You don't need to reference IoC library in all your projects\layers, even if you have registrations defined inside these
layers. A very simple set of wrapper classes will allow you to
abstract away from IoC specifics anywhere except your entry point.
When your application has several entry points, reusable registration will greatly help to prevent repeating the same
registration. This copy\paste is always bad. And applications have
several entry points quite often. For example, consider the scenario
of cross-platform application having a separate entry point for
every platform it targets. Or business logic reused in web site and
in background process.
With reusable registration, you can build a very effective testing system. You will be able to run a whole layer from tests,
mock whole layers in automated way, and do it very effectively,
minimizing efforts on writing tests.
See my blog article illustrating these points in more detail, with a working sample.
I have a modular application, it behaves quite like a plugin system. Module B is dependent on Module A. When B is present, then some dialogs (titles etc.) need to be altered in Module A. Also, a different entity should be used for a list when Module B is present, which I want to include in Module B, so A doesn't know about it during compile time. Creating an abstract base in A for the entity is something I want to avoid as well.
How would you implement this requirement? The modules can communicate in various ways:
1.) Microsoft Unity is used for Object creation and dependency injection
2.) The modules can communicate via a Message-System.
3.) There's an EventAggregator which all the modules can use
I don't want to sublcass the dialog in Module B and just alter the typemapping in unity, because then I'd have to provide the whole dialog in another module. Also, if some other module wants to make other changes to the dialog, it'd be impossible.
Suggestions welcome!
Without knowing specific details, I would use interfaces to blend the plug-in components/modules. Require that each plug-in component implement an interface -- say IPluginComponent or whatever makes sense. (Actually, only components that must communicate or interact would actually be required to implement the interface.) Once all modules are loaded, the host application can fire methods or events on the components.
Personally, I like to keep things data-driven and simple as much as possible; so I might favor a "two-phase" pass through the modules. This keeps the dependencies between modules simple. So in the first phase, when all components are loaded, the host application fires the "ContributeSharedData(Context ctx)" method, where each component sets any values in a shared context. (This might also be called "Init(ctx)".) The context might be as simple as a name-value-pair collection, e.g. Module B says *coll["ModuleB_Installed"] = true*, or it could add itself to a list of modules, or... the possibilities are endless. The context can be whatever class or structure is required to enable these components to work together.
The next pass -- if required -- would be for the components/modules to configure themselves based on the shared context. So the host might run through all the modules supporting the shared interface and fire the "Configure" method or event. Then ModuleA for instance can look in the context and see that ModuleB is installed, and configure its interface accordingly.
If an interface doesn't make sense for your situation, you can use any method of contributing shared data in a generic way to a common location, e.g. messaging or other common classes.
Hope this helps!
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.
I've started playing with Ninject and from a screencast it states the following is how you set up a binding:
class MyModule : StandardModule {
public override void Load() {
Bind<IInterface>().To<ConcreteType>();
// More bindings here...
}
}
This is all very good.
However suppose you have one hundred objects used in an application. That would mean this would have one hundred bindings. Is this correct?
Secondly, I presume that given such an application it may be split into subsystems such as GUI, Database, Services and so on.
Would you then create a custom module for each subsystem which in turn would be:
GUIModule
DatabaseModule
ServiceModule
...
For each module you'd have the correct bindings that they required. Am I on the right page here?
Finally would this binding all occur in Main or the entry point for your application?
However suppose you have one hundred
objects used in an application. That
would mean this would have one hundred
bindings. Is this correct?
One hundred registered components, yes, but not necessarily registered one by one. There's a Convention extension for Ninject that allows you to scan assemblies and register types based on some defined rules. See this test as an example.
Would you then create a custom module
for each subsystem
Again, not necessarily. You might just want to register all your repositories (just to name something) in a single convention registration.
For each module you'd have the correct
bindings that they required.
As with any "module" (be it assembly, class, application) the concepts of coupling and cohesion apply here as well. It's best practice to keep coupling low (don't depend too much on other modules) and cohesion high (all components within a module must serve towards a common goal)
Finally would this binding all occur
in Main or the entry point for your
application?
Yes, see this related question.