binding configuration to Names in guice recursively - configuration

My application has configurations which are loaded using parsing annotations into a file using Jackson's fasterxml annotations. For example:
public class RootConfiguration extends Configuration {
#JsonProperty
#NotEmpty
public String foo;
#JsonProperty
public BarConfiguration bar;
public class BarConfiguration extends Configuration {
#JsonProperty
public String baz;
}
}
The configuration is then injected into providers in my Module that help me bind those properties to places in the code that use them. Like so:
#Provides
#Named("config")
public RootConfiguration provideRootConfiguration(RootConfiguration configuration) {
return configuration;
}
#Provides
#Named("config.foo")
public String provideFooConfiguration(RootConfiguration configuration) {
return configuration.foo;
}
#Provides
#Named("config.bar")
public BarConfiguration provideBarConfiguration(RootConfiguration configuration) {
return configuration.bar;
}
And so on.
I'm looking for a framework to help me avoid this tedious work.
I would imagine something that looks like this:
#Configuration(value = "config", bindSubProperties = true)
public class RootConfiguration extends Configuration {
...
That would use Reflection to bind any sub fields in my class as guice Names.
I've looked into Governator's annotations for configurations but as far as I can see they need to be applied to every configuration that I want to bind, which saves me some coding, but is essentially the same (I still have to manually specify the path for each and every configuration I want to bind).
Before I roll out my own implementation for this, is there something that will give me what I need?
Note: I'm using this for a Dropwizard project so the constraint on using Jackson to map the configuration to POJOs is rather tight (unless I move the application configuration outside of the config yaml).

I don't know of any tool that would do this for you, but you could do it yourself pretty easily with something like this:
void bindConfiguration() {
for (Field field : RootConfiguration.class.getFields() {
bindConfiguration(TypeLiteral.get(field.getGenericType()), field);
}
}
<T> void bindConfiguration(TypeLiteral<T> type, Field field) {
bind(type)
.annotatedWith(Names.named("config." + field.getName()))
.toProvider(new ConfigurationProvider<T>(field))
.in(Singleton.class);
}
class ConfigurationProvider<T> implements Provider<T> {
private final Field field;
#Inject RootConfiguration configuration;
ConfigurationProvider(Field field) {
this.field = field;
}
#Override
public T get() {
return (T) field.get(configuration);
}
}

Related

How to use annotation based configuration to configure multiple buckets in Couchbase?

In the Couchbase documentation the below is given as an example to configure the environment. What would be done for having more than one bucket ?
#Configuration
public class Config extends AbstractCouchbaseConfiguration {
#Override
protected List<String> getBootstrapHosts() {
return Collections.singletonList("127.0.0.1");
}
#Override
protected String getBucketName() {
return "beer-sample";
}
#Override
protected String getBucketPassword() {
return "";
}
}
For multiple buckets in 2.0.x branch, the way it currently works is that you have to instantiate a second Bucket bean and the associated CouchbaseTemplate (that's the hardest part):
//we want all User objects to be stored in a second bucket
//let's define the bucket reference...
#Bean
public Bucket userBucket() {
return couchbaseCluster().openBucket("users", "");
}
//... then the template (inspired by couchbaseTemplate() method)...
#Bean
public CouchbaseTemplate userTemplate() {
CouchbaseTemplate template = new CouchbaseTemplate(
couchbaseClusterInfo(), //reuse the default bean
userBucket(), //the bucket is non-default
mappingCouchbaseConverter(), translationService() //default beans here as well
);
template.setDefaultConsistency(getDefaultConsistency());
return template;
}
After that, you'll probably also want some of your repositories to use this second template (and bucket). There's currently an implementation for that as well (RepositoryOperationsMapping), but it's probably going to change a bit until upcoming 2.0.0-RC so I won't go into details there.

StructureMap3 How to configure constructor string injection for all types?

I have registered my types using
Scan(
scan => {
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.With(new ControllerConvention());
});
But how do I specify for constructor injection with out having to specify the concrete type like this?
string connStr = "...";
For<IRepository().Use<MyRepository>().Ctor<string>("connectionString").Is(connStr);
You can create dedicated convention for registration of repositories.
public class RepositoryConvention : IRegistrationConvention
{
private const string ConnectionString = "your connection string";
public void Process(Type type, Registry registry)
{
if (type.IsConcrete() && type.GetInterfaces().Contains(typeof(IRepository)))
{
registry.For(typeof(IRepository))
.Use(type)
.CtorDependency<string>("connectionString")
.Is(ConnectionString);
}
}
}
or create dedicated type to provide with connection string. I bet you are getting it from web/app.config so adding abstraction for accessing it would be helpful anyway.
public interface IConfigurationSettingsReader
{
string ReadConnectionString(string name);
T ReadSetting<T>(string settingName);
}
Then you just add it as a dependency for your MyRepository and you don't need to add it explicitly in registration or use custom convention.
public class MyRepository : IRepository
{
private readonly string connectionString;
public MyRepository(IConfigurationSettingsReader settingsReader)
{
this.connectionString = settingsReader.ReadConnectionString("ConnStrName");
}
}
You can consider creating an abstract base repository class to be inherited by each repository to get rid of setup bolerplate.
Hope this helps!

Generic Singleton and share data between pages

To share data (complexe data ) between pages in my windows phone 8 application I want to implement a singleton, but I want it to be generic, is it possible? I suppose that it creates a new instance for each type isn't it?
public sealed class NavigationContextService<T>
{
private static readonly NavigationContextService<T> instance = new NavigationContextService<T>();
private NavigationContextService()
{
}
public static NavigationContextService<T> Instance
{
get
{
return instance;
}
}
public List<T> ShareList { get; set; }
public T ShareData { get; set; }
}
It is creating a new instance for every type, because it is generic - you want it to be like this (if you start with generics, take a look at some tutorials, blogs or MSDN - you will easily find many in the internet).
It is still a singleton. When you use
NavigationContextService<string>.Instance.ShareList.Add("Text");
then you have one Instance for type string. Generics helps a lot when you want to create same methods/classes that differ in type.
On the other hand if you want to create Singleton that will hold different types then you can for example modify your class to be non Generic like this:
public sealed class NavigationContextServiceNonGeneric
{
private static readonly NavigationContextServiceNonGeneric instance = new NavigationContextServiceNonGeneric();
private NavigationContextServiceNonGeneric() { ShareList = new List<object>(); }
public static NavigationContextServiceNonGeneric Instance
{ get { return instance; } }
public List<object> ShareList { get; set; }
public object ShareData { get; set; }
}
As you can see in the code above I haven't defined the 'exact' type of shared data - it is object type. Then you can easily hold most of data with it:
NavigationContextServiceNonGeneric.Instance.ShareList.Add("Text");
NavigationContextServiceNonGeneric.Instance.ShareList.Add(3);
NavigationContextServiceNonGeneric.Instance.ShareList.Add(3.0f);
It is singleton, which can hold different types of shared data. BUT it has also disavantages - the main is that you have to remember what type of data you hold and in what order. In my opinion Generic version is better because of that fact.
Everything depends on the purpose of your code. There may be easier and better ways that those two approaches.
As for the Page Navigation, you can for example try to use a method from this article - you extend Navigation service to pass the object:
public static class Extensions
{
private static object Data;
public static void Navigate(this NavigationService navigationService, Uri source, object data)
{
Data = data;
navigationService.Navigate(source);
}
public static object GetNavigationData(this NavigationService service) { return Data; }
}
Then you use it:
NavigationService.Navigate(yourUri, DataToPass);
After Navigation you can get your data:
string myTextData = NavigationService.GetNavigationData() as string;
This method has to disadvantages: it is not type-safe and your data won't be preserved in Tombstone mode.
As for the second disadvantage you can easily use PhoneApplicationService.State Property for the purpose of Page Navigation - it is a dictionary (which is preserved while tombstoning):
PhoneApplicationService.Current.State.Add("data", yourData);
Then when you want to get your data:
yourDataType yourData = PhoneApplicationService.Current.State["data"] as yourDataType;
There are also more ways in which you can pass the data.

Changing IRepository to support IQueryable (LINQtoSQL queries)

I've inherited a system that uses the Castle Windsor IRepository pattern to abstract away from the DAL which is LinqToSQL.
The main problem that I can see, is that IRepository only implements IEnumerable. So even the simplest of queries have to load ALL the data from the datatable, to return a single object.
Current usage is as follows
using (IUnitOfWork context2 = IocServiceFactory.Resolve<IUnitOfWork>())
{
KpiFormDocumentEntry entry = context2.GetRepository<KpiFormDocumentEntry>().FindById(id, KpiFormDocumentEntry.LoadOptions.FormItem);
And this uses lambda to filter, like so
public static KpiFormDocumentEntry FindById(this IRepository<KpiFormDocumentEntry> source, int id, KpiFormDocumentEntry.LoadOptions loadOptions)
{
return source.Where( qi => qi.Id == id ).LoadWith( loadOptions ).FirstOrDefault();
}
So it becomes a nice extension method.
My Question is, how can I use this same Interface/pattern etc. but also implement IQueryable to properly support LinqToSQL and get some serious performance improvements?
The current implementation/Interfaces for IRepository are as follows
public interface IRepository<T> : IEnumerable<T> where T : class
{
void Add(T entity);
void AddMany(IEnumerable<T> entities);
void Delete(T entity);
void DeleteMany(IEnumerable<T> entities);
IEnumerable<T> All();
IEnumerable<T> Find(Func<T, bool> predicate);
T FindFirst(Func<T, bool> predicate);
}
and then this is implemented by an SqlClientRepository like so
public sealed class SqlClientRepository<T> : IRepository<T> where T : class
{
private readonly Table<T> _source;
internal SqlClientRepository(Table<T> source)
{
if( source == null ) throw new ArgumentNullException( "source", Gratte.Aurora.SHlib.labelText("All_TableIsNull",1) );
_source = source;
}
//removed add delete etc
public IEnumerable<T> All()
{
return _source;
}
public IEnumerator<T> GetEnumerator()
{
return _source.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
The problem at the moment is, in our example above, the .Where is calling 'GetEnumerator', which then loads all rows into memory, and then looks for the one we need.
If I change IRepository to implement IQueryable, I can't implement the three methods needed, as these are not public in the Table class.
I think I should change the SQLClientRepository to be defined like so
public sealed class SqlClientRepository<T> : IQueryable<T>, IRepository<T> where T : class
And then implement the necessary methods, but I can't figure out how to pass the expressions around etc. as they are private members of the Table class, like so
public override Type ElementType
{
get { return _source.ElementType; } //Won't work as ElementType is private
}
public override Expression Expression
{
get { return _source.Expression; } //Won't work as Expression is private
}
public override IQueryProvider Provider
{
get { return _source.Provider; } //Won't work as Provider is private
}
Any help really appreciated to move this from 'iterate through every row in the database after loading it' to 'select x where id=1'!
If you want to expose linq you can stop using the repository pattern and use Linq2Sql directly. The reason to this is that every Linq To Sql provider has it's own custom solutions. So if you expose LINQ you get a leaky abstraction. There is no point in using an abstraction layer then.
Instead of exposing LINQ you got two options:
Implement the specification pattern
Use the repository pattern as I describe here: http://blog.gauffin.org/2013/01/repository-pattern-done-right/
So, while it may not be a true abstraction any longer, the main point was to get the benefit of linq to sql without updating all the queries already written.
so, I made the IRepository implement IQueryable instead of IEnumerable.
then in the SqlClientRepository implementation, I can call AsQueryable() to cast the Table to IQueryable, and then all is good, like so.
Now everywhere somebody has written IRepository().Where(qi => qi.id = id) or similar, it actually passes the ID to sql server and only pulls back one record, instead of all of them, and loops through looking for the correct one.
/// <summary>Provides the ability to query and access entities within a SQL Server data store.</summary>
/// <typeparam name="T">The type of entity in the repository.</typeparam>
public sealed class SqlClientRepository<T> : IRepository<T> where T : class
{
private readonly Table<T> _source;
private readonly IQueryable<T> _sourceQuery;
IQueryable<T> Query()
{
return (IQueryable<T>)_source;
}
public Type ElementType
{
get { return _sourceQuery.GetType(); }
}
public Expression Expression
{
get { return _sourceQuery.Expression; }
}
public IQueryProvider Provider
{
get { return _sourceQuery.Provider; }
}
/// <summary>Initializes a new instance of the <see cref="SqlClientRepository{T}"/> class.</summary>
/// <param name="source">A <see cref="Table{T}"/> to a collection representing the entities from a SQL Server data store.</param>
/// <exception cref="ArgumentNullException"><paramref name="source"/> is a <c>null</c> reference (<c>Nothing</c> in Visual Basic).</exception>
internal SqlClientRepository(Table<T> source)
{
if( source == null ) throw new ArgumentNullException( "source", "All_TableIsNull" ) );
_source = source;
_sourceQuery = _source.AsQueryable();
}

CDI: How to take care of beans configuration?

In CDI, how do I configure my beans?
Let's say I have this code:
class JawaBotApp {
private void init( String configFilePathString ) throws JawaBotException {
ConfigBean cb = new JaxbConfigPersister(configFilePathString).load();
JawaBotApp.jawaBot = JawaBot.create( cb );
}
}
class JawaBot {
public static JawaBot create( ConfigBean cb ) throws JawaBotException{
JawaBot bot = new JawaBot();
bot.applyConfig(cb);
bot.init();
return bot;
}
}
How would I convert it so both could be CDI beans?
I thought about annotating the create() with #Produces, however that would need to have it non-static, and rewrite it so the ConfigBean gets injected, which would need to rewrite JaxbConfigPersister or create a wrapper object... Too much work for nothing.
Is there better approach?
Something like:
class JawaBot {
#Inject public JavaBot(#JawaConfig String configFilePathString) {
...
}
}
Then you just need to produce an #JawaConfig String somewhere which represents your configuration. This could then be mocked out with something like an alternative or specialize to give you a diff config, or just some silly little #Producer that looks at some other external file/setting.
Then you just #Inject a JawaBot when you want it instead of all the other setup, and everything just lives in the injected constructor.