Cleaner way to register collections with Unity 3 - inversion-of-control

I usually use Autofac but this client requires we use Unity on their project. The ability to register by matching interface is nice and is saving some time from when I had to use version 2. I'm still finding collections to be a bit combersome. Is there an technique that would allow me to be able to add new IPrePopulationModule instances without having to register them individually like I have to below?
container.RegisterType<IPrePopulationModule, PopulateGenders>("PopulateGenders", new PerHttpRequestLifetimeManager());
container.RegisterType<IPrePopulationModule, PopulateOrigins>("PopulateOrigins", new PerHttpRequestLifetimeManager());
container.RegisterType<IPrePopulationModule, PopulateRelationshipTypes>("PopulateRelationshipTypes", new PerHttpRequestLifetimeManager());
container.RegisterType<IPrePopulationModule, PopulateRepresentationTypes>("PopulateRepresentationTypes", new PerHttpRequestLifetimeManager());
container.RegisterType<IPrePopulationModule, PopulateRuleSets>("PopulateRuleSets", new PerHttpRequestLifetimeManager());
container.RegisterType<IEnumerable<IPrePopulationModule>, IPrePopulationModule[]>();

Unity 3 added registration by convention to handle cases like this...
//There's other options for each parameter (and you can supply your own custom options)
container.RegisterTypes(
AllClasses.FromLoadedAssemblies().
Where(type => typeof(IPrePopulationModule).IsAssignableFrom(type)),
WithMappings.FromAllInterfacesInSameAssembly,
WithName.TypeName,
type => new PerHttpRequestLifetimeManager());

Related

Wiremock response of a certain regex

I have to send a random value back from wiremocked response. I have seen examples using {{randomValue type='ALPHANUMERIC'}}
However I could not find anything where I can give randomvalue of a particular regex - say alphanumeric value which starts with ABC and 9 random digits.
I did try -
{{randomValue regex='ABC[0-9]{9}'}}
But this is not working. I am not sure if there is any other way to do this.Please guide me to any appropriate resource if available.
The only way to do this currently is via a custom Handlebars helper.
You can provide custom helpers when creating the templating transformer during startup e.g.
WireMockServer wm = new WireMockServer(wireMockConfig()
.dynamicPort()
.extensions(new ResponseTemplateTransformer(
false,
Collections.singletonMap("myHelper", new MyHelper()))
)
);
Where MyHelper should extend the HandlebarsHelper abstract class.

How to convert List<Objects> to an ObservableRangeCollection

I am using Xamarin Forms and their templates come with MvvMHelpers object to be used in the ViewModel as ObservableRangeCollections. I know ObservableCollections. If you try to do :
ObservableRangeCollection<Object> collection = new ObservableRangeCollection<Object>();
List<Object> objects = new List<Objects>();
collection.ReplaceRange(objects);
//error invalid type
Does anyone know how to use an ObservableRangeCollection? There is nothing on it in Google, Bing or StackOverflow.
Try the search you'll see Xamarin is promoting something so new that nobody knows what it is.
ObservableRangeCollection is a helper class by the Xamarin Evangelist James Montemagno.
The source is available in his github:
https://github.com/jamesmontemagno/mvvm-helpers
ObservableRangeCollection intends to help when adding/replacing Collections to a ObservableCollection.
In a "regular" ObservableCollection, for each new item added to the Collection, a OnCollectionChanged event would raise.
This is where ObservableRangeCollection gets in. It allows to replace/add elements to the Collection without firing an event for each element.
ObservableRangeCollection is subclassed from ObservableCollection.
So in your example, substitute your <T>, i.e:
ObservableRangeCollection<string> collection = new ObservableRangeCollection<string>();
List<string> objects = new List<string>();
collection.ReplaceRange(objects);
Consult the code here: https://github.com/jamesmontemagno/mvvm-helpers/blob/master/MvvmHelpers/ObservableRangeCollection.cs
This is not something that new. There's plenty of code using ObservableCollection.
What you are trying to achieve can be done like this:
List<Object> myList = new List<Objects>();
ObservableCollection<Object> myCollection = new ObservableCollection<Object>(myList);
Read more about ObservableCollection.
Check out my answer here, which is an enhanced version of ObservableRangeCollection optimized for less event raising and reuse of items in UI.

Laravel 4 using vendor classes

I have installed Laravel 4 after using 3, love it.
I used to be able to use the Zend framework as such:
$yt = new Zend_Gdata_YouTube();
for instance
I have used composer to install Zend and everything is installed in the Vendor folder..
Problem:
How to address the individual classes i.e. Zend Gdata etc.
I can't find any documentation on calling classes from a vendor in L4.
Any help is appreciated.
Take a look at your vendor\composer\autoload_classmap.php file. In there you will find a list of all vendor classes that are being autoloaded. I think all classes will have to be called using their full namespaced name.
E.g.
I'm using Zizaco's Entrust package. This is what it looks like in the vendor\composer\autoload_classmap.php file.
'Zizaco\\Entrust\\Entrust' => $vendorDir . /zizaco/entrust/src/Zizaco/Entrust/Entrust.php',
If I wanted to access the Entrust.php class I have to call
$en = new Zizaco\Entrust\Entrust();
Alternatively you could alias certain classes in your app\config\app.php file.
E.g.
'Ent' => 'Zizaco\Entrust\Entrust'
In your case you'll need to do something like this:
$yt = new Zend\namespace\Zend_Gdata_YouTube();

Autofac: resolving different params to object using DependencyResolver

I am building an MVC application and have the need to send a different cachecontext (wraps info on which cache to use) into my repositories using the DependencyResolver. There are 10 different types of cachecontexts that can be passed in. At the moment, I am using 10 different registrations for 10 different types of interfaces (ICacheContexts). This works but does not seem like the correct way of handling this circumstance. Is there a way to create a factory that knows the object type it is being passed to so I can just determine the correct CacheContext to return and thus only have one registration to maintain?
Current code:
builder.Register(c => new CacheContext(AppConfig.AppBucketName, AppConfig.AppBucketpassword))
.As<ICacheContextForApps>();
builder.Register(c => new CacheContext(AppConfig.AcctBucketName, AppConfig.AcctBucketpassword))
.As<ICacheContextForAccounts>();
etc..
You need to do this from the repository side - for each repository, configure its parameters to resolve the right cache context. E.g. (paraphrasing)
builder.Register(c => new CacheContext(...for appls...))
.Named<ICacheContext>("apps");
builder.RegisterType<AppsRepository>()
.WithParameter((pi, c) => pi.ParameterType == typeof(ICacheContext),
(pi, c) => c.ResolveNamed<ICacheContext>("apps"));
Hope this gets you on the right track.

Problem with DSL and Business Rules creation in Drools

I am using Eclipse with the Drools plugin to create rules.
I want to create business rules and main aim is to try and provide the user a set of options which he can use to create rules.
For eg:If an Apple can have only 3 colors: I want to provide an option like a drop down so that the user can know before hand which are the options he can use in his rules.
Is it possible?
I am creating a dsl but unable to still provide the above functionality for a business rule.
I am having an error implementing a basic dsl also.
The code to add the dsl is as follows in my RuleRunner class()
InputStream ruleSource = RuleRunner.class.getClassLoader().getResourceAsStream("/Rule1.dslr");
InputStream dslSource = RuleRunner.class.getClassLoader().getResourceAsStream("/sample-dsl.dsl");
//Load the rules , using DSL
addRulesToThisPackage.addPackageFromDrl(
new InputStreamReader(ruleSource),new InputStreamReader(dslSource));
I have both the sample-dsl .dsl and Rule1.dslr in my working directory.
Error encountered at adding the dsl to the package (last line)
Error stack:
Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source)
at java.io.InputStreamReader.<init>(Unknown Source)
at com.org.RuleRunner.loadRuleFile(RuleRunner.java:96)
at com.org.RuleRunner.loadRules(RuleRunner.java:48)
at com.org.RuleRunner.runStatelessRules(RuleRunner.java:109)
at com.org.RulesTest.main(RulesTest.java:41)
my dsl file has basic mapping as per the online documentations.
The dsl rule I created is:
expander sample-dsl.dsl
rule "A status changes B status"
when
There is an A
- has an address
There is a B
- has name
then
- print updated A and Aaddress
End
I have created DSL in eclipse.
Is the code I added for it to be loaded to my package correct?? Or am I missing something????
It seems like my program is unable to find the dsl?
Please help. Can you point me towards the right direction to create a user friendly business rule ??
Thanks.
J
I am not quite familiar with the method you are trying to use to create a knowledge session, but I will show a example of what's used in my applications.
KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase(<KnowledgeBaseConfiguration>);
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newClassPathResource( "rules/myRuleFile.drl", getClass() ),
ResourceType.DRL );
kbuilder.add( ResourceFactory.newClassPathResource( "rules/myDslFile.dsl", getClass() ),
ResourceType.DSL );
if ( kbuilder.hasErrors() ) {
System.err.println( builder.getErrors().toString() );
}
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
Now as far as giving your users the ability to author rule files, with built in constraints, have you looked at Drools Guvnor?(http://downloads.jboss.com/drools/docs/5.0.1.26597.FINAL/drools-guvnor/html_single/index.html) I have not incorporated it into my project yet, but have researched it a bit. I think it may provide the functionality your seeking for allowing your users to create and edit rule files. Good luck!