[Export(typeof(IStringsTransformInstanciator))]
public class InvertCharsPerStringTransformInstanciator : IStringsTransformInstanciator
{
internal InvertCharsPerStringTransformInstanciator()
}
public IStringsTransform CreateInstance()
return new InvertCharsPerStringTransform();
public override string ToString()
return TransformResources.InvertCharsPerStringTransform;
public class NumberPerStringTransformInstanciator : IStringsTransformInstanciator
internal NumberPerStringTransformInstanciator()
return new NumberPerStringTransform();
return TransformResources.NumberPerStringTransform;
public class UpperTransform : PerStringTransformBase
protected override string Do(string line)
return line.ToUpper();
return TransformResources.Upper;
public class UpperTransformInstanciator : IStringsTransformInstanciator
return new UpperTransform();
[Import]
IEnumerable<IStringsTransform> _transforms;
private void FileTransformForm_Load(object sender, EventArgs e)
var transformsContainer = new CompositionContainer(new DirectoryCatalog("."));
var batch = new CompositionBatch();
batch.AddPart(this);
transformsContainer.Compose(batch);
traitementCombo.DataSource = _transforms;
public static class FileTransform
private static Dictionary<string, BackgroundWorker> _transformsRunning =
new Dictionary<string, BackgroundWorker>();
private static object _lockObject = new object();
public static void Transform(string inFilePath, string outFilePath,
IEnumerable<IStringsTransformInstanciator> transforms, Action<string> showError,
Func<string, bool> showErrorWithRetry, Action<bool, string> transformDone)
var transform = new CompositeStringsTransform(transforms);
if (!(File.Exists(inFilePath) || _transformsRunning.ContainsKey(inFilePath)))
FileNotFoundShowError(inFilePath, showError);
else if (!Directory.Exists(Path.GetDirectoryName(outFilePath)))
DirectoryNotFoundShowError(outFilePath, showError);
else
var bg = new BackgroundWorker();
bg.DoWork += (s, e) =>
e.Result = false;
while (true)
try
FileUtil.WriteLines(outFilePath, transform.Do(FileUtil.GetLines(inFilePath)));
e.Result = true;
catch (FileNotFoundException)
catch (DirectoryNotFoundException)
catch (IOException)
if (showErrorWithRetry(string.Format(ErrorResources.IOException, outFilePath)))
continue;
catch (Exception ex)
showError(string.Format(ErrorResources.FileNotFoundException,
string.Concat(ex.GetType(), " : ", ex.Message)));
break;
lock (_lockObject)
_transformsRunning.Remove(outFilePath);
};
bg.RunWorkerCompleted += (s, e) =>
if (transformDone != null)
transformDone((bool)e.Result, transform.ToString());
StartBGAndCache(inFilePath, outFilePath, bg);
private static void StartBGAndCache(string inFilePath, string outFilePath, BackgroundWorker bg)
RunWorkerCompletedEventHandler runWorkerCompletedTryAgain = null;
Action<BackgroundWorker> tryAgain = (bgTryAgain) =>
bgTryAgain.RunWorkerCompleted -= runWorkerCompletedTryAgain;
if (_transformsRunning.ContainsKey(inFilePath))
var bgTryAgain = _transformsRunning[inFilePath];
runWorkerCompletedTryAgain = (s, e) => tryAgain(bgTryAgain);
bgTryAgain.RunWorkerCompleted += runWorkerCompletedTryAgain;
else if (_transformsRunning.ContainsKey(outFilePath))
var bgTryAgain = _transformsRunning[outFilePath];
_transformsRunning.Add(outFilePath, bg);
bg.RunWorkerAsync();
private static void DirectoryNotFoundShowError(string directoryPath, Action<string> showError)
showError(string.Format(ErrorResources.DirectoryNotFoundException, Path.GetDirectoryName(directoryPath)));
private static void FileNotFoundShowError(string filePath, Action<string> showError)
showError(string.Format(ErrorResources.FileNotFoundException, filePath));
private void runBtn_Click(object sender, EventArgs e)
FileTransform.Transform(inFilePathTB.Text, outFilePathTB.Text, transformsLB.Items.Cast<IStringsTransform>(),
message => MessageBox.Show(message, Resources.ErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error),
message => MessageBox.Show(message, Resources.ErrorTitle, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error)
== DialogResult.Retry,
(result, transformName) =>
if (result)
transformsDoneLB.Items.Add(
string.Concat(transformName, " ", Resources.Done, ". ",
inFilePathTB.Text, " -> ", outFilePathTB.Text));
});