开发者

ASP.NET plugin architecture: reference to other modules

We're currently migrating our ASP Intranet to .NET and we started to develop this Intranet in one ASP.NET website. This, however, raised some problems regarding Visual Studio (performance, compile-time, ...).

Because our Intranet basically exists of modules, we want to seperate our project in subprojects in Visual Studio (each module is a subproject). This raises also some problems because the modules have references to each other. Module X uses开发者_C百科 Module Y and vice versa... (circular dependencies).

What's the best way to develop such an Intranet?

I'll will give an example because it's difficult to explain.

We have a module to maintain our employees. Each employee has different documents (a contract, documents created by the employee, ...).

All documents inside our Intranet our maintained by a document module.

The employee-module needs to reference the document-module.

What if in the future I need to reference the employee-module in the document-module?

What's the best way to solve this?


It sounds to me like you have two problems.

First you need to break the business orientated functionality of the system down into cohesive parts; in terms of Object Orientated design there's a few principles which you should be using to guide your thinking:

  • Common Reuse Principle
  • Common Closure Principle

The idea is that things which are closely related, to the extent that 'if one needs to be changed, they all are likely to need to be changed'.

  • Single Responsibility Principle

Don't try to have a component do to much.

I think you also need to look at you dependency structure more closely - as soon as you start getting circular references it's probably a sign that you haven't broken the various "things" apart correctly. Maybe you need to understand the problem domain more? It's a common problem - well, not so much a problem as simply a part of designing complex systems.

Once you get this sorted out it will make the second part much easier: system architecture and design.

Luckily there's already a lot of existing material on plugins, try searching by tag, e.g:

  • https://stackoverflow.com/questions/tagged/plugins+.net
  • https://stackoverflow.com/questions/tagged/plugins+architecture

Edit:

Assets is defined in a different module than employees. But the Assets-class defines a property 'AssignedTo' which is of the type 'Employee'. I've been breaking my head how to disconnect these two

There two parts to this, and you might want to look at using both:

  • Using a Common Layer containing simple data structures that all parts of the system can share.
  • Using Interfaces.

Common Layer / POCO's

POCO stands for "Plain Old CLR Objects", the idea is that POCO's are a simple data structures that you can use for exchanging information between layers - or in your case between modules that need to remain loosely Coupled. POCO's don't contain any business logic. Treat them like you'd treat the String or DateTime types.

So rather than referencing each other, the Asset and Employee classes reference the POCO's.

The idea is to define these in a common assembly that the rest of your application / modules can reference. The assembly which defines these needs to be devoid of unwanted dependencies - which should be easy enough.

Interfaces

This is pretty much the same, but instead of referring to a concrete object (like a POCO) you refer to an interface. These interfaces would be defined in a similar fashion to the POCO's described above (common assembly, no dependencies).

You'd then use a Factory to go and load up the concrete object at runtime. This is basically Dependency Inversion.

So rather than referencing each other, the Asset and Employee classes reference the interfaces, and concrete implementations are instantiated at runtime.

This article might be of assistance for both of the options above: An Introduction to Dependency Inversion

Edit:

I've got the following method GetAsset( int assetID ); In this method, the property asset.AssignedTo (type IAssignable) is filled in. How can I assign this properly?

This depends on where the logic sits, and how you want to architect things.

If you have a Business Logic (BL) Layer - which is mainly a comprehensive Domain Model (DM) (of which both Asset and Employee were members), then it's likely Assets and Members would know about each other, and when you did a call to populate the Asset you'd probably get the appropriate Employee data as well. In this case the BL / DM is asking for the data - not isolated Asset and Member classes.

In this case your "modules" would be another layer that was built on top of the BL / DM described above.

I variation on this is that inside GetAsset() you only get asset data, and atsome point after that you get the employee data separately. No matter how loosely you couple things there is going to have to be some point at which you define the connection between Asset and Employee, even if it's just in data.

This suggests some sort of Register Pattern, a place where "connections" are defined, and anytime you deal with a type which is 'IAssignable' you know you need to check the register for any possible assignments.


I would look into creating interfaces for your plug-ins that way you will be able to add new modules, and as long as they follow the interface specifications your projects will be able to call them without explicitly knowing anything about them.

We use this to create plug-ins for our application. Each plugin in encapsulated in user control that implements a specific interface, then we add new modules whenever we want, and because they are user controls we can store the path to the control in the database, and use load control to load them, and we use the interface to manipulate them, the page that loads them doesn't need to know anything about what they do.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜