|
I wasn't really looking for general information on app globalisation, I've developed a few globalised apps in my time but I've not been in my current specific situation and wondered if there was a relevant pattern.
Thanks anyway.
|
|
|
|
|
The "recommended patterns" are there. I find it's not worth the effort to go against the grain in these situations. Adopt; then extend, if necessary.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
I might not have explained my question properly to be honest.
Localising an application using Resx and custom UI binders for XAML, iOS and Android Xamarin apps is fine. I've done all these things before. Handling RTL globalisation in WPF apps is also something I've done before as well.
I was basically looking for inspiration regarding taking localised strings from RESX files and populating various database tables with lookup values for things.
What I've ended up doing is implementing the Builder pattern to aggregate key value pairs from these RESX files and utilising my repository pattern bits to automatically populate these lookup tables on the initial creation of the SQLite db3 file.
My base builder class looks like this (not perfect by a long shot, there is no abstraction of the connection I can use for instance):
public abstract class LookupBuilderBase<T> where T : class, IEntity, new()
{
protected SQLiteAsyncConnection AsyncConnection;
protected IDictionary<string, string> LookupData;
protected IRepository<T> Repository;
protected readonly IList<T> Data = new List<T>();
protected LookupBuilderBase(SQLiteAsyncConnection conn, IDictionary<string, string> lookupData)
{
AsyncConnection = conn;
LookupData = lookupData;
}
public async Task Execute()
{
CreateRepository();
BuildData();
await InsertData();
}
protected abstract void BuildData();
protected virtual async Task InsertData()
{
foreach (var item in Data)
{
await Repository.Insert(item);
}
}
private void CreateRepository()
{
Repository = new Repository<T>(AsyncConnection);
}
}
I can then write builders like this:
public class CategoryBuilder : LookupBuilderBase<Category>
{
public CategoryBuilder(SQLiteAsyncConnection conn, IDictionary<string, string> lookupData)
: base(conn, lookupData)
{
}
protected override void BuildData()
{
var values = LookupData.Where(x => x.Key.StartsWith("Category"));
foreach (var keyValuePair in values)
{
Data.Add(new Category { Name = keyValuePair.Value });
}
}
}
|
|
|
|
|
I would have a single table (for a given "dimension") and have columns for each resource.
At run-time, using Linq, or C# / SQL "views" (or some other magic), I would materialize only the column that the app's locale required.
Adapters.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
It's either a case of filter what you're interested in on the way into the database or shove it all in there and filter on the way out of the database.
I opted to only put relevant stuff into the database which means that considering the data is 99.99999999% handled in reads not writes I opted to make the read more efficient.
|
|
|
|
|
"Shove it in there"?
It becomes THE repository for your resources; and not just some "staging area".
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
That's what RESX files are ...
|
|
|
|
|
Then why are you loading them into a table....
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
In the instance of Categories it's because they are simple lookup values loaded into a view model for, for example, binding to a combobox. BUT they are also useful as values used in foreign key relationship in the database.
Resex is the best way to handle automatic localisation utilising standardised approaches for this in the .NET framework but also have value in the database.
|
|
|
|
|
I see.
I, however, would not think twice about loading it all into a database if I had to "share" in the ways you describe; let alone report on and cross-check all this stuff for any sizable project.
Resx internals are simple; there is nothing stopping one from importing or exporting them.
It's a question of which "smell" one prefers then.
In any case, the "assets" are separated from the "code"; the whole point of "resource files" (whatever the implementation).
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Not sure if I understood your issue completely. Since you want to let the user edit the texts, you opted for storing them in a database instead of resx files, but still want to use resx files for development, isn't it? I'd suggest to get rid of those resx files here, handle the localization completely in the database (I think software translation shops can handle that, too), thus no need to feed them from the files into the database.
|
|
|
|
|
I have the following code structure:
[CODE]
bool bStop = true;
int RowCount = 65000;
private void btnRun_Click(object sender, EventArgs e)
{
int i = 0;
//int iErr;
while (i < dataGridView1.Rows.Count - 1 && bStop)//Loop 1
{
while (i < dataGridView1.Rows.Count - 1 && bStop)// Loop 2
{
try
{
if (i > 0) dataGridView1.Rows[i-1].Selected = false;
dataGridView1.Rows[i].Selected = true;
dataGridView1["ROWS", i].Value = "Processing...";
System.Windows.Forms.Application.DoEvents();
Thread.Sleep(1000);
Debug.Print("are in Try and i: " + i);
}
catch (Exception ex)
{
Debug.Print("are in Catch and i: " + i + " ex: " + ex.Message);
}
i++;
}
}
}
[/CODE]
|
|
|
|
|
It does - that's the whole point.
You use the try block to catch and handle exceptions, and the code will continue from the line immediately after the catch block.
Since your whole try...catch block is inside your loop, the loop will continue:
int j = 0;
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
try
{
i = i / j;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Gives:
0
Attempted to divide by zero.
1
Attempted to divide by zero.
2
Attempted to divide by zero.
3
Attempted to divide by zero.
4
Attempted to divide by zero.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I ran outside with structures on the run very good but when I use add the AT command set and add progress is no way to escape the catch, you know what commands to delete all errors in the catch ?
|
|
|
|
|
I'm sorry, but that didn't make any sense to me - it may be that I haven't had my yet, but I'm working on it - could you try again, this time remembering that I can't see your screen or access your HDD, and only get exactly what you type to work from?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
according to my above code results when run debug: Show output from debug
are in Try and i: 0
are in Try and i: 1
are in Try and i: 2
are in Try and i: 3
are in Try and i: 4
are in Try and i: 5
are in Try and i: 6
are in Try and i: 7
are in Try and i: 8
are in Try and i: 9
are in Try and i: 10
are in Try and i: 11
are in Try and i: 12
are in Try and i: 13
are in Catch and i: 14
are in Catch and i: 15
are in Catch and i: 16
are in Catch and i: 17
are in Catch and i: 18
are in Catch and i: 19
...
|
|
|
|
|
Try running it without a debugger.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Dear
I'm newbie and i'm developing a Windows Service which should make same tasks according some REGISTRY KEY i will populate during Setup Setup (based on VS c# Setup Project).
I need to rollback installation before complete installation if during Setup a web request i run give me back some errors or some special return value.
How can I do using custom action ?
thx
nemo14
|
|
|
|
|
Don't use the registry unless you have no other option: access to it is now restricted, and likely to become more so, not less.
Instead, consider using an XML file (or similar) stored in a more accessible location. Windows provides several: Where should I store my data?[^] and it's a lot easier to just dump a folder on rollback than play with the registry.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Apart from the fact that OriginalGriff is right telling you not to use the registry, your main issue was not solved by his answer: where to do a rollback. Since you talk about a Windows Service, you should have a ServiceInstaller in your project. Then you'll do some overrides, e.g. Rollback , OnBeforeRollback , OnAfterRollback . Which ever you select, do not forget to call base.YourSelectedFunction .
|
|
|
|
|
here i am giving a small my code snippet just to show what i am trying to achieve.
private void frmMain_Load(object sender, EventArgs e)
{
ISchedulerFactory schedFact = new StdSchedulerFactory();
sched = schedFact.GetScheduler();
sched.Start();
IJobDetail job = JobBuilder.Create<frmMain>()
.WithIdentity("Job", "group")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule
(s =>
s.WithIntervalInHours(24)
.OnEveryDay()
.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(01, 55))
)
.Build();
sched.ScheduleJob(job, trigger);
}
public void Execute(IJobExecutionContext context)
{
generate();
}
public void generate()
{
if (this.FetchStart != null)
this.FetchStart(this, new EventArgs());
System.Threading.Thread.Sleep(5000);
if (this.FetchDone != null)
this.FetchDone(this, new EventArgs());
}
i have done my project with VS2013 community edition. my objective is to call slide show routine every day at specific time. when i am calling my slide show routine without quartz.net scheduler then it is working fine but when i invoke my routine by quartz.net scheduler then routine is getting called but no slide show image is showing.
what [problem occur is not clear to me. as per my objective i have to use quartz.net scheduler because i need to invoke my routine at a specific time of day every day.
here i am sharing my project code because it is in onedrive. so my request please some one download my project and run at your end to see the problem and tell me the reason which causes not to show images on picture box.
if possible please rectify my code with quartz.net scheduler code. one drive project link is https://1drv.ms/f/s!AmIfMNV-CodPa81zFiNH6Ur7qro
i upload my project folder.
thanks
----------------------------------------------------------------------------------------------------------
UPDATE
when i use background worker along with quartz.net to call my generate routine then also no improvement i found. same problem that slide show image is not appearing on picture box.
here is the code for quartz.net with background worker
public partial class frmMain : Form, IJob
{
ucSlide oSlide = new ucSlide();
IScheduler sched = null;
BackgroundWorker m_oWorker = null;
public event EventHandler FetchStart;
public event EventHandler FetchDone;
public event EventHandler NoDataFound;
public frmMain()
{
InitializeComponent();
m_oWorker = new BackgroundWorker();
m_oWorker.DoWork += new DoWorkEventHandler(m_oWorker_DoWork);
m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted);
oSlide.MainForm = this;
oSlide.SlideSource = Utility.SlidePath;
this.Controls.Add(oSlide);
oSlide.Dock = DockStyle.Fill;
}
private void frmMain_Load(object sender, EventArgs e)
{
ISchedulerFactory schedFact = new StdSchedulerFactory();
sched = schedFact.GetScheduler();
sched.Start();
IJobDetail job = JobBuilder.Create<frmMain>()
.WithIdentity("Job", "group")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule
(s =>
s.WithIntervalInHours(24)
.OnEveryDay()
.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(02,23))
)
.Build();
sched.ScheduleJob(job, trigger);
}
public void Execute(IJobExecutionContext context)
{
m_oWorker.RunWorkerAsync();
}
public void generate()
{
if (this.FetchStart != null)
this.FetchStart(this, new EventArgs());
System.Threading.Thread.Sleep(5000);
if (this.FetchDone != null)
this.FetchDone(this, new EventArgs());
}
void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
{
generate();
}
void m_oWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
thanks
tbhattacharjee
|
|
|
|
|
No one is going to download a project to fix it for you. If there is an issue with Quartz.Net, the github for it can be found here[^].
This space for rent
|
|
|
|
|
Functional programming mayhem. Reap now what you sow.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Is there any third party spell checker extension like javascript spell checker to implement in my web api c# project?
I tried javascript spell checker it is working in local perfect. Once publish in online it is showing some message like register and purchase.
Please post is there any free extension because it is urgent for me due client doesn't want to purchase.
|
|
|
|
|