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.
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
![Smile :) :)](/styles/default/custom/smilies/smile.gif)
).
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