Localization Service

S

shapper

Hello,

I am creating a localization service for a web site. My idea is
something has follows:

public class LocalizationService {
private IDictionary<String, String> _phrases = new
Dictionary<String, String>();

public LocalizationService() {
_phrases.Add("Name", "Nome");
} // LocalizationService

public String GetPhrase(String key) {
return _phrases[key].ToString();
} // GetPhrase

} // LocalizationService

In this case I am providing the key to get a phrase.
But I would need to provide the key and the language.

For example, for languages EN, PT and ES to store the values:
"Name", "Nome", "Nombre" with Key "Name".

Then being able to take a phrase given it's key and language.
Or get various phrases given, for example an array of keys, and the
language.

What would be the best approach to implement this?
I think I should make use a IDictionary with an object ...

I am not sure the best way to do this.

Thanks,
Miguel
 
P

Peter Duniho

shapper said:
Hello,

I am creating a localization service for a web site. My idea is
something has follows:

public class LocalizationService {
private IDictionary<String, String> _phrases = new
Dictionary<String, String>();

public LocalizationService() {
_phrases.Add("Name", "Nome");
} // LocalizationService

public String GetPhrase(String key) {
return _phrases[key].ToString();
} // GetPhrase

} // LocalizationService

In this case I am providing the key to get a phrase.
But I would need to provide the key and the language.

For example, for languages EN, PT and ES to store the values:
"Name", "Nome", "Nombre" with Key "Name".

Then being able to take a phrase given it's key and language.
Or get various phrases given, for example an array of keys, and the
language.

What would be the best approach to implement this?

My recollection is that .NET already has support for localization. I
admit, not being something I've used personally I don't know the
details. But my first attempt would be to research what support .NET
already has and take advantage of it.

If you want to implement it yourself, I see at least two obvious
elaborations on what you've already got:

-- One dictionary for each language
-- An array of strings for each phrase

Using the former, you'd use the language code to select the dictionary
before looking up the phrase. Using the latter, the language code would
be some kind of enumeration that can be used as an index into an array,
while the single dictionary would map phrase keys to arrays of possible
localized values.

Retrieving a phrase might look like this:

IDictionary<string, IDictionary<string, string>> _languages = new
Dictionary<string, IDictionary<string, string>>();

public LocalizationService()
{
IDictionary<string, string> phrases;

phrases = new Dictionary<string, string>();
phrases.Add("Name", "Name");
_languages.Add("EN", phrases);

phrases = new Dictionary<string, string>();
phrases.Add("Name", "Nome");
_languages.Add("PT", phrases);

phrases = new Dictionary<string, string>();
phrases.Add("Name", "Nombre");
_languages.Add("ES", phrases);
}

public string GetPhrase(string key, string lang)
{
return _languages[lang][key];
}

Or:

enum Language
{
EN = 0,
PT = 1,
ES = 2,
}

IDictionary<string, string>[] _languages;

public LocalizationService()
{
_languages = new IDictionary[Language.GetValues().Length];

IDictionary<string, string> phrases;

phrases = new Dictionary<string, string>();
phrases.Add("Name", "Name");
_languages[Language.EN] = phrases;

phrases = new Dictionary<string, string>();
phrases.Add("Name", "Nome");
_languages[Language.PT] = phrases;

phrases = new Dictionary<string, string>();
phrases.Add("Name", "Nombre");
_languages[Language.ES] = phrases;
}

public string GetPhrases(string key, Language lang)
{
return _languages[lang][key];
}

Or:

enum Language
{
EN = 0,
PT = 1,
ES = 2,
}

IDictionary<string, string[]> _phrases;

public LocalizationService()
{
_phrases = new Dictionary<string, string[]>;

string[] rgstr;

rgstr = new string[Language.GetValues().Length];

rgstr[Language.EN] = "Name";
rgstr[Language.PT] = "Nome";
rgstr[Language.ES] = "Nombre";

_phrases.Add("Name", rgstr);
}

public string GetPhrases(string key, Language lang)
{
return _languages[key][lang];
}

There are a number of similar approaches you could take.

Whatever you do, I wouldn't not actually put the data for the
initialization of the localization information in the code itself.
Hopefully the code you posted is just a "for example", and not really
how you intend to represent the initial values for the dictionary(ies).
(That's certainly the only reason the examples above I wrote have the
data hard-coded in the constructor).

Personally, I would prefer the first example. It's somewhat easier to
add new languages using that approach, and it gives you the option of
loading only languages you know you'll actually need to translate
(possibly dynamically, depending on who's using the web site at the
time, which could help with memory footprint).

Finally, note that at least with localization systems I've used in the
past, it's common to use numerical constants to identify phrases, rather
than actual strings. Strings are a fairly "heavyweight" way to specify
phrases for use in code.

Pete
 
S

shapper

shapper said:
I am creating a localization service for a web site. My idea is
something has follows:
  public class LocalizationService {
    private IDictionary<String, String> _phrases = new
Dictionary<String, String>();
    public LocalizationService() {
      _phrases.Add("Name", "Nome");
    } // LocalizationService
    public String GetPhrase(String key) {
      return _phrases[key].ToString();
    } // GetPhrase
  } // LocalizationService
In this case I am providing the key to get a phrase.
But I would need to provide the key and the language.
For example, for languages EN, PT and ES to store the values:
"Name", "Nome", "Nombre" with Key "Name".
Then being able to take a phrase given it's key and language.
Or get various phrases given, for example an array of keys, and the
language.
What would be the best approach to implement this?

My recollection is that .NET already has support for localization.  I
admit, not being something I've used personally I don't know the
details.  But my first attempt would be to research what support .NET
already has and take advantage of it.

I know the NET localization system but to be honest I don't like it
very much.

I have a table on the SQL database named Assets where I save texts
(plain, html, etc) and Files.
Each asset, whatever type is used, is saved in Binary data with a
column for Mime type.
Usually, these assets are contents to be edited by the users.

The localization system I am talking would be more specific to the
application like:
In a form I have a few labels "Name:", "Email:", etc. So I would use
this in the localization service.

Probably it would be to place this also on the Assets table and have a
column "Locked" that would allow the administrator to edit it or not
instead of having this hard coded.

The other approach I am considering is using two tables, instead of
the one name Assets: Phrases and Files.

Phrases would hold text data like strings, CSS code, JS code, HTML
code, etc.
Files would hold files in binary data with its binary data.

In both cases I would have a column named MimeType and another one
named Locked.
The Locked would determine if the administrator can edit it or not.

And following your example I would use the Id as key of the content.

To have localization I can have 4 tables:
Phrases and PhrasesLocalized
Files and FilesLocalized

And I think differentiating the textual data from the binary data in
two tables would be a better approach then having what I have now
which is a common table Assets.

What do you think?
If you want to implement it yourself, I see at least two obvious
elaborations on what you've already got:

     -- One dictionary for each language
     -- An array of strings for each phrase

Using the former, you'd use the language code to select the dictionary
before looking up the phrase.  Using the latter, the language code would
be some kind of enumeration that can be used as an index into an array,
while the single dictionary would map phrase keys to arrays of possible
localized values.

Retrieving a phrase might look like this:

   IDictionary<string, IDictionary<string, string>> _languages = new
Dictionary<string, IDictionary<string, string>>();

   public LocalizationService()
   {
     IDictionary<string, string> phrases;

     phrases = new Dictionary<string, string>();
     phrases.Add("Name", "Name");
     _languages.Add("EN", phrases);

     phrases = new Dictionary<string, string>();
     phrases.Add("Name", "Nome");
     _languages.Add("PT", phrases);

     phrases = new Dictionary<string, string>();
     phrases.Add("Name", "Nombre");
     _languages.Add("ES", phrases);
   }

   public string GetPhrase(string key, string lang)
   {
     return _languages[lang][key];
   }

This was my idea.
I wasn't sure how to have this multi dimension with Dictionary.

About defining the values on the constructor I have exactly the same
problem with a validatorFactory.

I was filling the dictionary on the constructor.
The problem is on a class I was initializing the factory outside the
methods.
Some methods would use others not.
So the validators were being added even the method didn't use them.

So maybe having the validatorFactory defined outside the methods but
adding the values to the Dictionary not on initialization but have
GetValidator to call a method Register that initializes it.

This way, I can have validatorFactory defined outside the methods and
the Dictionary filled only when GetValidator is called.

Does this make sense?

Do you want me to post my code for this?

Thanks,
Miguel
 
P

Peter Duniho

shapper said:
[...]
I have a table on the SQL database named Assets where I save texts
(plain, html, etc) and Files.
Each asset, whatever type is used, is saved in Binary data with a
column for Mime type.
Usually, these assets are contents to be edited by the users.

The localization system I am talking would be more specific to the
application like:
In a form I have a few labels "Name:", "Email:", etc. So I would use
this in the localization service.

Probably it would be to place this also on the Assets table and have a
column "Locked" that would allow the administrator to edit it or not
instead of having this hard coded.

[...]
What do you think?

I think as long as you don't have to go edit the code itself just to add
or update language translations, that's 80% of what's important right
there. The rest is implementation detail for you to decide, based on
the systems you're using already.
[...]
About defining the values on the constructor I have exactly the same
problem with a validatorFactory.

I was filling the dictionary on the constructor.

From a source of data, rather than as hard-coded values in the code
itself, right? (see above)
The problem is on a class I was initializing the factory outside the
methods.
Some methods would use others not.
So the validators were being added even the method didn't use them.

So maybe having the validatorFactory defined outside the methods but
adding the values to the Dictionary not on initialization but have
GetValidator to call a method Register that initializes it.

This way, I can have validatorFactory defined outside the methods and
the Dictionary filled only when GetValidator is called.

Does this make sense?

I agree that you should not initialize data structures that are not
related to the code being executed. Why your validation code interacts
with the localization code, I'm not sure (displaying validation
errors?). But it does sound like you might need to refactor your code
to avoid irrelevant dependencies.

On the other hand, beware of too much deferred initialization. If you
have an opportunity to initialize a data structure you know you'll need
eventually, but to do it when the user won't notice the delay, deferring
initialization until the data is actually needed could be worse, causing
a delay in output that could have been avoided.

I think the biggest issue is more of a design question than a
functionality issue. In particular, a constructor should not take very
long to execute. If you have some extensive initialization to perform,
it would be better to put that in a factory method somewhere, that can
either pass pre-initialized data to a private constructor, or can
initialize the object after calling a private constructor.

For me, the main reason to follow this approach (but not the only) is
that there's a correlation between complexity of code and time of
execution. I mean, you can write a simple block of code that takes a
long time to execute, but usually if your constructor takes a long time
to execute it's because it's doing something much more significant than
just getting the object into a coherent state.

And if it's doing that, it also is much more likely to be passing the
"this" reference from the constructor to other code, which is generally
a bad idea, even if passed to a private method in the class. You should
do your best to avoid letting the "this" reference escape the
constructor, because it can lead to uses of the object before the
object's internal data structures have been completely initialized.

It's also just plain nicer to know that an object can be constructed
quickly, even if there is some time-consuming initialization that still
remains to be done afterwards.
Do you want me to post my code for this?

Can you fit it on a page? Honestly, broad design questions are
difficult to answer in a newsgroup, because often there's way too much
information to deliver and process. We all have limited time, and a
question that's too complicated will often go unanswered (especially on
a weekday :) ).

But if you have a concise way to describe the code and/or design, feel
free to share.

Pete
 
S

shapper

shapper said:
[...]
I have a table on the SQL database named Assets where I save texts
(plain, html, etc) and Files.
Each asset, whatever type is used, is saved in Binary data with a
column for Mime type.
Usually, these assets are contents to be edited by the users.
The localization system I am talking would be more specific to the
application like:
In a form I have a few labels "Name:", "Email:", etc. So I would use
this in the localization service.
Probably it would be to place this also on the Assets table and have a
column "Locked" that would allow the administrator to edit it or not
instead of having this hard coded.
[...]
What do you think?

I think as long as you don't have to go edit the code itself just to add
or update language translations, that's 80% of what's important right
there.  The rest is implementation detail for you to decide, based on
the systems you're using already.

Agree.
I just decided to add this "little" localization strings and phrases
also to my current asset system which uses a SQL table.
[...]
About defining the values on the constructor I have exactly the same
problem with a validatorFactory.
I was filling the dictionary on the constructor.
 From a source of data, rather than as hard-coded values in the code
itself, right?  (see above)

The validators no ... Please, see further down to better understand my
code.
I agree that you should not initialize data structures that are not
related to the code being executed.  Why your validation code interacts
with the localization code, I'm not sure (displaying validation
errors?).  

Yes, to localize the error codes. Again see my code.
But it does sound like you might need to refactor your code
to avoid irrelevant dependencies.

On the other hand, beware of too much deferred initialization.  If you
have an opportunity to initialize a data structure you know you'll need
eventually, but to do it when the user won't notice the delay, deferring
initialization until the data is actually needed could be worse, causing
a delay in output that could have been avoided.

Understood but got lost in terms of implementation.
I think the biggest issue is more of a design question than a
functionality issue.  In particular, a constructor should not take very
long to execute.  If you have some extensive initialization to perform,
it would be better to put that in a factory method somewhere, that can
either pass pre-initialized data to a private constructor, or can
initialize the object after calling a private constructor.

For me, the main reason to follow this approach (but not the only) is
that there's a correlation between complexity of code and time of
execution.  I mean, you can write a simple block of code that takes a
long time to execute, but usually if your constructor takes a long time
to execute it's because it's doing something much more significant than
just getting the object into a coherent state.

And if it's doing that, it also is much more likely to be passing the
"this" reference from the constructor to other code, which is generally
a bad idea, even if passed to a private method in the class.  You should
do your best to avoid letting the "this" reference escape the
constructor, because it can lead to uses of the object before the
object's internal data structures have been completely initialized.

It's also just plain nicer to know that an object can be constructed
quickly, even if there is some time-consuming initialization that still
remains to be done afterwards.


Can you fit it on a page?  Honestly, broad design questions are
difficult to answer in a newsgroup, because often there's way too much
information to deliver and process.  We all have limited time, and a
question that's too complicated will often go unanswered (especially on
a weekday :) ).

But if you have a concise way to describe the code and/or design, feel
free to share.

Ok, I think it is better to use code.

Please, if there is some specific code I should post let me know.
I think I posted everything ...

This is my validatorFactory:

public class ValidatorFactory : IValidatorFactory {

private Dictionary<Type, IValidator> _validators = new
Dictionary<Type, IValidator>();

public ValidatorFactory() {
_validators.Add(typeof(ArticleForm), new ArticleFormValidator
());
_validators.Add(typeof(UserSignIn), new UserSignInValidator());
} // ValidatorFactory

public IValidator<T> GetValidator<T>() {
return (IValidator<T>)GetValidator(typeof(T));
} // GetValidator

public IValidator GetValidator(Type type) {
IValidator validator;
if (_validators.TryGetValue(type, out validator))
return validator;
return null;
} // GetValidator

} // ValidatorFactory


Question 1: Should I fill the dictionary in the constructor?
Please, read further for more details.

The problem is in my validators I will need to access the localization
service to get the error messages for each language.


Question 2: My idea is to add a LocalizationService to my validator
factory and to all validators:

public ValidatorFactory(LocalizationService service, Language
language) {
_validators.Add(typeof(ArticleForm), new ArticleFormValidator
(service, language));
_validators.Add(typeof(UserSignIn), new UserSignInValidator
(service, language));
} // ValidatorFactory

So from inside each validator I would be able to get the
needed localized error messages given the language.
Is this correct?


Question 3: I think I might be initializing adding dictionary values
when the factory is not really being used.
I am not sure the best way to structure my services and
factories but here it goes:


public class ArticleController : Controller {

private ISession _session;
private ArticleRepository _articleRepository;
private TwitterService _twitterService;
private LocalizationService _localizationService;
private ValidatorFactory _validatorFactory;

// Initialize
protected override void Initialize(RequestContext context) {
base.Initialize(context);
_session = new Context();
_articleRepository = new ArticleRepository(_session);
_localizationService = new LocalizationService();
_twitterService = new TwitterService();
_validatorFactory = new ValidatorFactory();
} // Initialize


public ActionResult Create() {

ArticleForm model = new ArticleForm()
return View(model);

} // Create

public ActionResult Create(ArticleForm model) {

_validatorFactory.GetValidator<ArticleForm>().Validate
(model).AddToModelState(ModelState, String.Empty);
if (ModelState.IsValid) {
_articleRepository.Create(Mapper.Map<ArticleForm, Article>
(model));
_session.Commit();
return RedirectToAction("List");
} else {
return View(model);
}

} // Create

public ActionResult Delete(Int32 id) {

_articleRepository.Delete(id);
_session.Commit();
return RedirectToAction("List");

} // Delete

// More methods

}

So not in all methods I use all services or repositories.
In repositories nothing is done unless I call a method.
So I think that is not problem.

But in validatorFactory the dictionary is being filled the moment I
initialize it.

My question is: What would be the best way to use my services,
repositories and factory in my controller?

And here is an example of a repository:

public class ArticleRepository {

public ArticleRepository(ISession session) {

// Check session
if (session == null)
throw new ArgumentNullException("session", "Session cannot be
null");
_context = (Context)session;

} // ArticleRepository

// Create
public void Create(Models.Article article) {

// Define entity
Entities.Article _article = new Entities.Article {
Created = DateTime.UtcNow,
Content = article.Content,
Excerpt = article.Excerpt,
File = article.File,
Key = Guid.NewGuid(),
Published = article.Published,
Title = article.Title,
Updated = DateTime.UtcNow
};
_context.Articles.InsertOnSubmit(_article);

} // Create

public void Delete(Int32 id) {

Entities.Article _article = _context.Articles.FirstOrDefault(a
=> a.Id == id);
_context.Articles.DeleteOnSubmit(_article);

} // Delete

} // ArticleRepository

Thank You,
Miguel
 
P

Peter Duniho

shapper said:
[...]
This is my validatorFactory:

public class ValidatorFactory : IValidatorFactory {

private Dictionary<Type, IValidator> _validators = new
Dictionary<Type, IValidator>();

public ValidatorFactory() {
_validators.Add(typeof(ArticleForm), new ArticleFormValidator
());
_validators.Add(typeof(UserSignIn), new UserSignInValidator());
} // ValidatorFactory

public IValidator<T> GetValidator<T>() {
return (IValidator<T>)GetValidator(typeof(T));
} // GetValidator

public IValidator GetValidator(Type type) {
IValidator validator;
if (_validators.TryGetValue(type, out validator))
return validator;
return null;
} // GetValidator

} // ValidatorFactory


Question 1: Should I fill the dictionary in the constructor?

The dictionary above is much different from the dictionary one might
need for localization. In particular, a) it's a lot smaller
(presumably) and b) it doesn't require i/o in order to perform the
initialization.

It's not that initializing dictionaries in a constructor is generally
bad. It's that when doing so can be time-consuming or require exposing
the "this" reference from the constructor, in those specific kinds of
scenarios it's bad.

So. In the code example above, I don't see any problem. Create your
dictionary and initialize it in the constructor. Should work fine.
Please, read further for more details.

The problem is in my validators I will need to access the localization
service to get the error messages for each language.


Question 2: My idea is to add a LocalizationService to my validator
factory and to all validators:

public ValidatorFactory(LocalizationService service, Language
language) {
_validators.Add(typeof(ArticleForm), new ArticleFormValidator
(service, language));
_validators.Add(typeof(UserSignIn), new UserSignInValidator
(service, language));
} // ValidatorFactory

So from inside each validator I would be able to get the
needed localized error messages given the language.
Is this correct?

I guess I don't really understand why your factory needs a reference to
the LocalizationService. In particular, I would _expect_ a localization
implementation to be basically "global" in nature. I.e. a singleton
class, or even a static class or static methods in a class.

Of course, to support specific languages, that service may in fact
return language-specific instances, of itself or some related class.
But as with the .NET culture-specific types, the language would be some
kind of persistent setting, and the service would just do the right
thing according to the current setting.

At most, code that needs the localization service would/could pass to a
factory method the language setting/code in use, and the service would
return an appropriate language-specific instance of a class to do the
actual localization work (the main service could cache these instances,
so that you don't create a new instance every time you need a localized
string).
Question 3: I think I might be initializing adding dictionary values
when the factory is not really being used.
I am not sure the best way to structure my services and
factories but here it goes:


public class ArticleController : Controller {

private ISession _session;
private ArticleRepository _articleRepository;
private TwitterService _twitterService;
private LocalizationService _localizationService;
private ValidatorFactory _validatorFactory;

// Initialize
protected override void Initialize(RequestContext context) {
base.Initialize(context);
_session = new Context();
_articleRepository = new ArticleRepository(_session);
_localizationService = new LocalizationService();
_twitterService = new TwitterService();
_validatorFactory = new ValidatorFactory();
} // Initialize

[...]
}

So not in all methods I use all services or repositories.
In repositories nothing is done unless I call a method.
So I think that is not problem.

But in validatorFactory the dictionary is being filled the moment I
initialize it.

Which dictionary is being filled the moment you initialize it? In the
code you posted here, the only dictionary I see is the one mapping types
to validators. That should be fine (as I mentioned above). On the
other hand, if you are trying to initialize all of the localization data
structures possible, just because you're creating a ValidatorFactory,
that would be a problem.
My question is: What would be the best way to use my services,
repositories and factory in my controller?

Sorry...that seems like a very broad question, and I don't feel like I
have enough information in any case. I don't have a good way to answer
that.

However, in terms of the localization service, if you do things as I
describe above, such that the validator and any other code that may need
localization of strings simply accesses a global object like static
methods or a singleton when they need to get the translated string, then
none of this other initialization matters.

You may find it useful to have some part of your initialization force
some initialization in the localization service. But that would not
happen as a result of initializing other classes; it would just be part
of the top-level initialization, or in response to specific user input
(e.g. selecting a specific language for use).

I'm not by any means trying to say that this is the only viable way to
do things. You may have some specific reason/need for keeping your
localization so closely tied to the validation code that I just don't
understand.

But I do know I've never done localization that way. It seems to me
that a more autonomous class that really does just act as a global
service, aware of every message that might ever be used in the
application and able to return translated instances of those messages on
demand, allows you to isolate functionality better and avoid undesirable
relationships between the initialization of disparate types.

Pete
 
S

shapper

shapper said:
[...]
This is my validatorFactory:
  public class ValidatorFactory : IValidatorFactory {
    private Dictionary<Type, IValidator> _validators = new
Dictionary<Type, IValidator>();
    public ValidatorFactory() {
      _validators.Add(typeof(ArticleForm), new ArticleFormValidator
());
      _validators.Add(typeof(UserSignIn), new UserSignInValidator());
    } // ValidatorFactory
    public IValidator<T> GetValidator<T>() {
      return (IValidator<T>)GetValidator(typeof(T));
    } // GetValidator
    public IValidator GetValidator(Type type) {
      IValidator validator;
      if (_validators.TryGetValue(type, out validator))
        return validator;
      return null;
    } // GetValidator
  } // ValidatorFactory
Question 1: Should I fill the dictionary in the constructor?

The dictionary above is much different from the dictionary one might
need for localization.  In particular, a) it's a lot smaller
(presumably) and b) it doesn't require i/o in order to perform the
initialization.

It's not that initializing dictionaries in a constructor is generally
bad.  It's that when doing so can be time-consuming or require exposing
the "this" reference from the constructor, in those specific kinds of
scenarios it's bad.

So.  In the code example above, I don't see any problem.  Create your
dictionary and initialize it in the constructor.  Should work fine.

True, I will never have more than 40 items in the dictionary and
usually only around 20.

But let me explain a situation:

When I display an image in a web page I have something like:
<img src="Images/Product.jpg"/>

So the image file is taken from the folder Images.
Using .NET MVC I can use the following:

<img src="<%=Url.Content("ProductController", "Get", new { Id =
ViewModel.Id })/>

So the ProductController is called and the Get Action (Method) is ran.
Instead of getting the image from the file I get it from the database
using the repository.
I return the image as byte to the view will display it.

Remember that on this call ProductController is inicialized and the
validatorFactory is initialized and items added to the dictionary.

Now consider that there is a page /view that has a product list with
40 products.

Well each image src will call the ProductController/Get method once.
So I will have 40 calls to Get and the validationFactory will be
initialized 40 times and each time the validators will be added to the
dictionary.

This seems like it will provoke some delay ... Am I wrong?
I guess I don't really understand why your factory needs a reference to
the LocalizationService.  In particular, I would _expect_ a localization
implementation to be basically "global" in nature.  I.e. a singleton
class, or even a static class or static methods in a class.

I don't understand exactly the global / static / singleton ...

I mean, each time there is a request for a view / page its controller
called and initialized and the correct method (Edit, Create, Show,
etc) is called. Inside this method the model is defined and returned
to the view.

How can a validatorFactory or localizationService be global if the
controller is only "present" when a view is requested ...

This is confusing me ...
Of course, to support specific languages, that service may in fact
return language-specific instances, of itself or some related class.
But as with the .NET culture-specific types, the language would be some
kind of persistent setting, and the service would just do the right
thing according to the current setting.

My localizationService will always, given a language, return a class
Asset with properties Id and Content.
Content value will be in the language provided.
Asset itself does not have any reference to the content language.
I don't need that. When I call localization service and provide a
language code all i need is to get that asset in that language.
At most, code that needs the localization service would/could pass to a
factory method the language setting/code in use, and the service would
return an appropriate language-specific instance of a class to do the
actual localization work (the main service could cache these instances,
so that you don't create a new instance every time you need a localized
string).
Question 3: I think I might be initializing adding dictionary values
when the factory is not really being used.
            I am not sure the best way to structure my services and
factories but here it goes:
  public class ArticleController : Controller {
    private ISession _session;
    private ArticleRepository _articleRepository;
    private TwitterService _twitterService;
    private LocalizationService _localizationService;
    private ValidatorFactory _validatorFactory;
    // Initialize
    protected override void Initialize(RequestContext context) {
      base.Initialize(context);
      _session = new Context();
      _articleRepository = new ArticleRepository(_session);
      _localizationService = new LocalizationService();
      _twitterService = new TwitterService();
      _validatorFactory = new ValidatorFactory();
    } // Initialize
[...]
  }
  So not in all methods I use all services or repositories.
  In repositories nothing is done unless I call a method.
  So I think that is not problem.
  But in validatorFactory the dictionary is being filled the moment I
initialize it.

Which dictionary is being filled the moment you initialize it?  In the
code you posted here, the only dictionary I see is the one mapping types
to validators.  That should be fine (as I mentioned above).  On the
other hand, if you are trying to initialize all of the localization data
structures possible, just because you're creating a ValidatorFactory,
that would be a problem.

My localizationService is, considering that I decided to use the
database for everything, AssetService which is on MyApp.Domain.
This said I can access it directly from anywhere on my
App.Presentation which is where I have the validators do validate the
ViewModels
Sorry...that seems like a very broad question, and I don't feel like I
have enough information in any case.  I don't have a good way to answer
that.

However, in terms of the localization service, if you do things as I
describe above, such that the validator and any other code that may need
localization of strings simply accesses a global object like static
methods or a singleton when they need to get the translated string, then
none of this other initialization matters.

I am never sure when to use static.
You may find it useful to have some part of your initialization force
some initialization in the localization service.  But that would not
happen as a result of initializing other classes; it would just be part
of the top-level initialization, or in response to specific user input
(e.g. selecting a specific language for use).

I'm not by any means trying to say that this is the only viable way to
do things.  You may have some specific reason/need for keeping your
localization so closely tied to the validation code that I just don't
understand.

No I don't need it ... I just though it was more correct to send the
service as a parameter than accessing it directly inside each
validator.
But I do know I've never done localization that way.  It seems to me
that a more autonomous class that really does just act as a global
service, aware of every message that might ever be used in the
application and able to return translated instances of those messages on
demand, allows you to isolate functionality better and avoid undesirable
relationships between the initialization of disparate types.

So I think that if I have my AssetService in App.Domain and access it
directly from anywhere in the App.Presentation controllers, validators
or helpers classes then I might be doing what you are suggesting.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top