I am working in the logical architecture of a project that receives some info from users and processes it. One of the requirements is to expose an interface for external developers to add further functionalities. So far I have proposed a MVC 2-tier architecture, where the View and Controller run in the user's machine, and the Model is hosted in an Application server and remotely invoked. The requirement on functionalities suggests me to use a plugin pattern.
Additional steps selected by the user might be executed when processing the information, so I wanted to model them as plugins that will already exist when the application is released. This means that this plugins would affect the same resource (the processing flow), and I am uncertain about how to deal with this when both plugins are enabled.
Since I am not as familiar with the plugin pattern as with other patterns, the reading I did before asking made me try something similar to the Abstract Factory pattern. The problem is that, when two or more plugins are enabled, I would need mutiple inheritance. I also thought of the Builder pattern to model steps of the processing separately, but then an order among plugins would have to be defined and this would affect the independence of plugin's developers.
If I understand correctly, you want to be able to extend the same variation point with multiple independent plugins. If so, the pipes and filters pattern is an appropriate mechanism.
With this approach, plugins represent filters and you can design a plugin container that loads and then chains them. If no plugin is loaded for a given variation point, then you either short-circuit the variation point or provide some form of default filter.
Also, giving the plugins a mechanism to specify their position in the filter chain will be helpful, so think about that when designing the plugin-interface.
Related
I have application which has core website, api and admin area. I wanted to know is it bad idea to have everything in one app or should I create different Symfony2 project or should I split them into different kernels?
I'm not sure if adding lots of bundles on same kernel will effect performance a lot or is just a little bit, which does not matter?
Following are options:
keep everything on same kernel, it wont make much difference
have multiple kernel for different part of application (api, admin and core website)
create different Symfony2 project for admin area and api.
or your wise words :)
You can define more "environments".
For example :
In AppKernel.php
public function registerBundles()
{
$bundles = array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
//new AppBundle\AppBundle()
);
if (in_array($this->getEnvironment(), array('api'), true)) {
$bundles[] = new ApiBundle\ApiBundle();
//-- Other bundle
}
//-- Other environments
return $bundles;
}
}
It mostly depends on bundles quality. And this how much connected they are.
I would reject point 3 at start (create different Symfony2 project for admin area and api.) - as probably you don't build two separate applications.
Have multiple kernel for different part of application (api, admin and core website)
Common problem is created by Listeners and services in container. Especially when your listener should work only in one of app contexts (api/frontend/backend). Even if you remember to check it at very beginning of listener method (and do magic only in wanted context) then still listener can depend on injected services which need to be constructed and injected anyway. Good example here is FOS/RestBundle: even if you configure zones then still on frontend (when view_listener is activated for api) view_handler is initialized and injected to listener - https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/config/view_response_listener.xml#L11 I'm not sure for 100% here but also disabling translations and twig (etc.) for API (most of api's don't need it) will speed it up.
Creating separate Kernel for API context would solve that issue (in our project we use one Kernel and we had to disable that listener - as blackfire.io profiles were telling us that it saves ~15ms on every fronted request).
Creating new Kernel for API would make sure that none of API-only services/listeners will not interfere with frontend/backend rendering (it work both ways). But it will create for you additional work of creating shared components used in many bundles inside project (those from different kernels) - but in world with composer it's not a huge task anymore.
But it's case only for people who measure every millisecond of response time. And depends on your/3dparty bundles quality. If all there is perfectly ok then you don't need to mess with Kernels.
It's personal choice, but I have a similar project and I have a publicBundle, adminBundle and apiBundle all within the same project.
The extra performance hit is negliable but organisation is key ... that is why we're using an MVC package (Symfony) in the first place, is it not? :)
NB: You terminology is a little confusing, I think by Kernel you mean Bundle.
Have several kernels could not necessarily help.
Split your application in bundles and keep all advantages of sharing your entities (and so on) through the different parts of your application.
You can define separated routing/controllers/configuration that are loaded depending on the host/url.
Note :
If you are going to separate your app in two big bundles (i.e. Admin & Api),
and that the two share the same entities, you will surely have to do a choice.
This choice may involves that one of your bundles contains too much (and non related) logic and will need to be refactored in several bundles later.
Create a bundle per section of your application that corresponds to a set of related resources and make difference between the two parts through different contexts from configuration.
Also, name your classes/namespaces sensibly.
I'm doing some in memory Caching for some Plugins in Microsoft CRM. I'm attempting to figure out if I need to be concerned about different orgs populating the same cache:
// In Some Plugin
var settings = Singleton.GetCache["MyOrgSpecificSetting"];
// Use Org specific cached Setting:
or do I need to do something like this to be sure I don't cross contaminate settings:
// In Some Plugin
var settings = Singleton.GetCache[GetOrgId() + "MyOrgSpecificSetting"];
// Use Org specific cached Setting:
I'm guessing this would also need to be factored in for Custom Activities in the AsyncWorkflowService as well?
Great question. As far as I understand, you would run into the issue you describe if you set static data if your assemblies were not registered in Sandbox Mode, so you would have to create some way to uniquely qualify the reference (as your second example does).
However, this goes against Microsoft's best practices in Plugin/Workflow Activity development. Every plugin should not rely on state outside of the state that is passed into the plugin. Here is what it says on MSDN found HERE:
The plug-in's Execute method should be written to be stateless because
the constructor is not called for every invocation of the plug-in.
Also, multiple system threads could execute the plug-in at the same
time. All per invocation state information is stored in the context,
so you should not use global variables or attempt to store any data in
member variables for use during the next plug-in invocation unless
that data was obtained from the configuration parameter provided to
the constructor.
So the ideal way to managage caching would be to use either one or more CRM records (likely custom) or use a different service to cache this data.
Synchronous plugins of all organizations within CRM front-end run in the same AppDomain. So your second approach will work. Unfortunately async services are running in separate process from where it would not be possible to access your in-proc cache.
I think it's technically impossible for Microsoft NOT to implement each CRM organization in at least its own AppDomain, let alone an AppDomain per loaded assembly. I'm trying to imagine how multiple versions of a plugin-assembly are deployed to multiple organizations and loaded and executed in the same AppDomain and I can't think of a realistic way. But that may be my lack of imagination.
I think your problem lies more in the concurrency (multi-threading) than in sharing of the same plugin across organizations. #BlueSam quotes Microsoft where they seem to be saying that multiple instances of the same plugin can live in one AppDomain. Make sure multiple threads can concurrently read/write to your in-mem cache and you'll be fine. And if you really really want to be sure, prepend the cache key with the OrgId, like in your second example.
I figure you'll be able to implement a concurrent cache, so I won't go into detail there.
I'm studying Prism and need to create a small demo app. I have some design questions. The differences between attitudes might be small, but I need to apply the practices to a large scale project later, so I'm trying to think ahead.
Assuming the classical DB related scenario - I need to get a list of employees and a double click on a list item gets extra information for that employee: Should the data access project be a module, or is a project accessed via repository pattern a better solution? What about large scale project, when the DB is more than one table and provides, say, information about employees, sales, companies etc.?
I'm currently considering to use the DataAccess module as a stand alone module, and have defined its interface in the Infrastructure project as well as its return type (EmployeeInformation). This means that both my DataAccess module and my application have to reference the Infrastructure project. Is this a good way to go?
I'm accessing said DataAccess module using ServiceLocator (MEF) from my application. Should the ServiceLocator be accessed by parts of the application, or is it meant to be used in the initialization section only?
Thanks.
A module is needed and makes sense when it contains ine part of the application that can live on it's own. This can be parts of an application the only several people need or are allowed to use, e.g. the user management module only administrators are allowed to access. But your data access layer is not that kind of isolated functionality that usually goes into a module. It is better placed in a common assembly the real modules can use. The problem here is that all modules depend on this DAL assembly, so have the task of updating your DAL in mind when designing your application (downward compatibility).
Usually there is no problem to have types that are broadly used reside in a common assembly. But this is not the infrastructure assembly. Infrastructure, as the word implies, provides services to have the modules work together. Your common types should go into something like YourNamespace.Types or YourNamespace.Client.Base or ...
This is a topic in many arguments and still unclear (at least from my point of view). Purists of Dependency Injection say it should only be used during initialization. Pragmatists are using the ServiceLocator all over their application.
We are developing a web-application (lets call it an image bank) for which we have identified the following needs:
The application caters customers which consist of a set of users.
A new customer can be created dynamically and a customer manages it's users
Customers have different feature sets which can be changed dynamically
Customers can develop their own features and have them deployed.
The application is homogeneous and has a current version, but version lifting of customers can still be handled individually.
The application should be managed as a whole and customers share the resources which should be easy to scale.
Question: Should we build this on a standard OSGi framework or would we be better of using one of the emerging application frameworks (Virgo, Aries or upcoming OSGi standard)?
More background and some initial thoughts:
We're building a web-app which we envision will soon have hundreds of customers (companies) with hundreds of users each (employees), otherwise why bother ;). We want to make it modular hence OSGi. In the future customers themselves might develop and plugin components to their application so we need customer isolation. We also might want different customers to get different feature sets.
What's the "correct" way to provide different service implementations to different clients of an application when different clients share the same bundles?
We could use the app-server approach (we've looked at Virgo) and load each bundle once for each customer into their own "app". However it doesn't feel like embracing OSGi. We're not hosting a multitude of applications, 99% of the services will share the same impl. for all customers. Also we want to manage (configure, monitor etc.) the application as one.
Each service could be registered (properly configured) once for each customer along with some "customer-token" property. It's a bit messy and would have to be handled with an extender pattern or perhaps a ManagedServiceFactory? Also before registering a service for customer A one will need to acquire the A-version of each of it's dependencies.
The "current" customer will be known to each request and can be bound to the thread. It's a bit of a mess having to supply a customer-token each time you search for a service. It makes it hard to use component frameworks like blueprint. To get around the problem we could use service hooks to proxy each registered service type and let the proxy dispatch to the right instance according to current customer (thread).
Beginning our whole OSGi experience by implementing the workaround (hack?) above really feels like an indication we're on the wrong path. So what should we do? Go back to Virgo? Try something similar to what's outlined above? Something completely different?!
ps. Thanks for reading all the way down here! ;)
There are a couple of aspects to a solution:
First of all, you need to find a way to configure the different customers you have. Building a solution on top of ConfigurationAdmin makes sense here, because then you can leverage the existing OSGi standard as much as possible. The reason you might want to build something on top is that ConfigurationAdmin allows you to configure each individual service, but you might want to add a layer on top so you can more conveniently configure your whole application (the assembly of bundles) in one go. Such a configuration can then be translated into the individual configurations of the services.
Adding a property to services that have customer specific implementations makes a lot of sense. You can set them up using a ManagedServiceFactory, and the property makes it easy to lookup the service for the right customer using a filter. You can even define a fallback scenario where you either look for a customer specific service, or a generic one (because not all services will probably be customer specific). Since you need to explicitly add such filters to your dependencies, I'd recommend taking an existing dependency management solution and extending it for your specific use case so dependencies automatically add the right customer specific filters without you having to specify that by hand. I realize I might have to go into more detail here, just let me know...
The next question then is, how to keep track of the customer "context" within your application. Traditionally there are only a few options here, with a thread local context being the most used one. Binding threads to customers does tend to limit you in terms of implementation options though, as in general it probably means you have to prohibit developers from creating threads themselves, and it's hard to off-load certain tasks to pools of worker threads. It gets even worse if you ever decide to use Remote Services as that means you will completely loose the context.
So, for passing on the customer identification from one component to another, I personally prefer a solution where:
As soon as the request comes in (for example in your HTTP servlet) somehow determine the customer ID.
Explicitly pass on that ID down the chain of service dependencies.
Only use solutions like the use of thread locals within the borders of a single bundle, if for example you're using a third party library inside your bundle that needs this to keep track of the customer.
I've been thinking about this same issue (I think) for some time now, and would like your opinions on the following analogy.
Consider a series of web application where you provide access control using a single sign-on (SSO) infrastructure. The user authenticates once using the SSO-server, and - when a request comes in - the target web application asks the SSO server whether the user is (still) authenticated and determines itself if the user is authorized. The authorization information might also be provided by the SSO server as well.
Now think of your application bundles as mini-applications. Although they're not web applications, would it still not make sense to have some sort of SSO bundle using SSO techniques to do authentication and to provide authorization information? Every application bundle would have to be developed or configured to use the SSO bundle to validate the authentication (SSO token), and validate authorization by asking the SSO bundle if the user is allowed to access this application bundle.
The SSO bundle maintains some sort of session repository, and also provides user properties, e.g. information to identify the data repository (of some sort) of this user. This way you also wouldn't pass trough a (meaningful) "customer service token", but rather a cryptic SSO-token that is supplied and managed by the SSO bundle.
Please not that Virgo is an OSGi container based on Equinox, so if you don't want to use some Virgo-specific feature, you don't have to. However, you'll get lots of benefits if you do use Virgo, even for a basic OSGi application. It sounds, though, like you want web support, which comes out of the box with Virgo web server and will save you the trouble of cobbling it together yourself.
Full disclosure: I lead the Virgo project.
For a large application that will be developed, we are in the process of selecting a Validation framework. Although the Workflow Rules engine is not strictly a Validation framework, it can be used by itself without using the Workflow foundation. It appears to give flexibility of specifying the rules in a database that is used at runtime. However, it appears that you cannot specify rules in the code.
If greater flexibility is one of the requirements (not necessarily that the rules need to be edited by Business analysts), which of the two would you prefer and why?
It quite matters in what your exact requirements are. 'Being flexible' is by itself not a good requirement, because it isn't measurable. It's very subjective if something is flexible.
I'm not familiar with Microsoft Business Rules Engine, so I can't comment on that. I am however very familiar with the Microsoft Enterprise Library Validation Application Block (VAB) and it has served me well over the last year. It has several features that make it flexible for the situations I’m dealing with:
It allows both defining validation declarative (using attributes) and using an external configuration file (which is very useful when your entities are generated).
It contains a set of default validators that can be used and custom validators can be written.
It allows validation of single properties and allows you compare multiple properties as a group (by using self validation or custom validators).
It allows validating objects in isolation, as well as object graphs.
It allows you to define multiple 'rule sets' which for instance allows you to define an set of hard errors and a set of warnings.
VAB (or the Enterprise Library as a whole) allows you write a custom configuration source (IConfigurationSource) which allows you to define your business rules wherever you want. So in theory you could store them in the database, however you will have to write such configuration source yourself, and this will be quite some work. Especially when you want your business analysts to be able to define validations and update the database with some sort of editing tool, it think this will be quite hellish to accomplish with VAB.
If there really is a requirement of the business people to write those rules themselves, hopefully you got process supporting this requirement. For instance, how are they going to test whether their changes are correct? You wouldn’t want your business analysts to make changes directly to the production database.
But please give this a thought. If the rules are going to be tested, I expect those rules not to be changed directly in your production database, otherwise you would be testing after the fact. So, the analysts would be changing the rules in their own environment and you’d probably be publishing the new rules from this environment to a test environment, and later on to acceptation environment and eventually to a production environment. And if you’re taking these steps, should you still use a database to store those business rules? Using a configuration file would make it much easier than using the database. Deployment would simply be a file copy instead of copying the content of multiple tables from database to database.
I'm interested in what others have to say about the validation frameworks they know well.