I have a program that receives files from clients and do some operations on files and save them on disk or won’t save them.
For decoupling of jobs, I created an interface named IFileEditor. Every component that do something on file, should implement this interface:
public interface IFileEditor
{
string Name { get; set; }
byte[] Content { get; set; }
string EditedName { get; set; }
byte[] EditedConent { get; set; }
string ComponentName { get; }
XmlDocument Config { get; set; }
XmlDocument Result { get; set; }
void EditFile(byte[] content);
}
Main method in this interface is EditFile that receives file contents and do operations, and maybe in last save the result on disk.
Sample class that I wrote is that create a thumbnail from image that implements this interface:
public class ThumbnailCreator : IFileEditor
{
public string Name { get; set; }
public byte[] Content { get; set; }
public sting EditedName { get; set; }
public byte[] EditedConent { get; set; }
public XmlDocument Config { get; set; }
public XmlDocument Result { get; set; }
public void EditFile(byte[] content)
{
//change the file content and save the thumbnail content in disk
}
}
I may have lots of components like ThumbnailCreator, for example zip content or anything else that do operation on content.
In main program I load every component by reflection. Implementation of loading them is not important, just know that copying ddl of component beside .exe of main program and if dll implements IFileEditor, I add that to list.
Main question is that, main application just receives files and pass them to components, and components do the jobs. If I want to pass the result of one component to another, what should I do?
Remember that components doesn't know each other and main program should not interfere in passing results.
I searched, and I think chain-of-responsibility design pattern will solve my question. I don’t know is that correct? If correct how to implement this?
For example one component creates the thumbnail and pass the result to compress the thumbnail.
I wrote this part like this, that every developer can create a component and main program could be extendable.
Thanks for reading this large post. ;)
Yes, the chain-of-responsibility pattern is what you could use to solve this design problem. You basically need to make sure that each processor knows the next processor in the chain and calls it and have some sort of runner that configures the processor chain once, starts the processing operation and collects the end result. There are many use cases for such a pattern, System.Net.Http.DelegatingHandler (http://msdn.microsoft.com/en-us/library/system.net.http.delegatinghandler(v=vs.110).aspx) works like this. Java ServletFilters are conceptually the same thing as well.
You could also just keep your processors in a collection, iterate that collection and apply each processor to your input by calling a specific method, i.e. EditFile in your example.
Update -- here's a naive implementaiton to illustrate what I mean (taken from LINQPad):
void Main()
{
// Variant 1 - Chaining
var editorChain = new UpperCaseFileEditor(new LowerCaseFileEditor());
var data1 = new char[] { 'a', 'B', 'c' };
editorChain.Edit(data1);
data1.Dump(); // produces ['a','b','c']
// Variant 2 - Iteration
var editors = new List<IFileEditor> { new LowerCaseFileEditor(), new UpperCaseFileEditor() };
var data2 = new char[] { 'a', 'B', 'c' };
foreach (var e in editors) {
e.Edit(data2);
}
data2.Dump(); // produces ['A','B','C']
}
// Define other methods and classes here
public interface IFileEditor {
IFileEditor Next { get; set; }
void Edit(char[] data);
}
public class UpperCaseFileEditor : IFileEditor {
public IFileEditor Next { get; set; }
public UpperCaseFileEditor() : this(null) {}
public UpperCaseFileEditor(IFileEditor next) {
Next = next;
}
public void Edit(char[] data) {
for (int i = 0; i < data.Length; ++i) {
data[i] = Char.ToUpper(data[i]);
}
if (Next != null)
Next.Edit(data);
}
}
public class LowerCaseFileEditor : IFileEditor {
public IFileEditor Next { get; set; }
public LowerCaseFileEditor() : this(null) {}
public LowerCaseFileEditor(IFileEditor next) {
Next = next;
}
public void Edit(char[] data) {
for (int i = 0; i < data.Length; ++i) {
data[i] = Char.ToLower(data[i]);
}
if (Next != null)
Next.Edit(data);
}
}
Please take into consideration that this is a just an illustration and I won't claim that this will scale to a production/real-world use case :-). Depending on what you really do, you might need to work on performance improvements, it might be quite handy to work with streams instead of byte/char arrays for example.
Related
Brief: I'm creating an MVC application in which I need to display a variety of types documents, some containing more author information than others.
What I wanna do: My approach is to have a generic "view document" view, which dynamically displays the document in a format dictated by the shape/type of the object passed to it.
Example: A simple document would be loaded into a SimpleDocumentViewModel, and display as such. However I'd like to load a larger type of document into an ExtendedDocumentViewModel, bringing with it additional information about both the document and the author. The view(s) would then display the appropriate data based on the object it receives.
Where I'm at now: In this vein I've created the following interfaces and classes, but I'm stuck as to how to return/identify the more specific return types in their derived classes.
abstract class BaseDocumentViewModel : DocumentViewModel, IDocumentViewModel
{
public int DocumentId { get; set; }
public string Body { get; set; }
public IAuthorViewModel Author { get; set; }
}
class SimpleDocumentViewModel : BaseDocumentViewModel
{
}
class ExtendedDocumentViewModel : BaseDocumentViewModel
{
public new IAuthorExtendedViewModel Author { get; set; }
}
interface IAuthorViewModel
{
int PersonId { get; set; }
string Name { get; set; }
}
interface IAuthorExtendedViewModel : IAuthorViewModel
{
int ExtraData { get; set; }
int MoreExtraData { get; set; }
}
Question: So my question is; how best can I get the specific types from the fully implemented classes, or do I need to return the base types and query it all in the view? Or am I off my head and need to go back to the drawing board?
Edits:
I know that c# doesn't support return type covarience, but hoped that there may be another way of returning/identifying the derived types so that I don't have to query them all in the view.
My current solution would be to always return the base types, and have a separate view for each concrete type that simply casts each object to the correct type, only querying those that could differ. Perhaps this is the best solution end of, but it feels very inelegant.
Usually you can do a simple "is" check. So you can have conditional rendering in your views, for example:
#if(Model is ExtendedDocumentViewModel)
{
// render ExtendedDocumentViewModel html here
}
Type checking is usually considered an anti pattern, however I am not sure if there is a much better approach to this problem. If you are using .NET Core you can also check the subclass tag here http://examples.aspnetcore.mvc-controls.com/InputExamples/SubClass .
Possible cleaner option is to just have a signature in the interface called GetView that each document has to implement. This way each document type has their own way of implementing the function and the calling function knows that each document has a function GetView. This method will work well if every document has a unique way of viewing the document. However if some documents share the same way of getting views, then may I suggest creating each View type into their own class and you can assign the views types to each document. I suggest looking into the strategy pattern.
First suggestion:
class SimpleDocumentViewModel : IAuthorViewModel
{
view GetView()
{
... do document specific stuff
... return view
}
}
class ExtendedDocumentViewModel : IAuthorViewModel
{
int ExtraData { get; set; }
int MoreExtraData { get; set; }
view GetView()
{
... do document specific stuff
... return view
}
}
interface IAuthorViewModel
{
view GetView();
}
Second suggestion:
class SimpleDocumentViewModel : IAuthorViewModel
{
public viewType1 view {get;set;}
public SimpleDocumentViewModel(viewType1 viewIn,etc...)
{
view = viewIn;
}
view GetView()
{
return view.GetView();
}
}
class ExtendedDocumentViewModel : IAuthorViewModel
{
int ExtraData { get; set; }
int MoreExtraData { get; set; }
public viewType2 view {get;set;}
public ExtendedDocumentViewModel(viewType2 viewIn,etc...)
{
view = viewIn;
}
view GetView()
{
return view.GetView(ExtraData,MoreExtraData);
}
}
interface IAuthorViewModel
{
view GetView();
}
I may be way off base here, but as I understand your question... why not just throw the return types in an object and pass that to your view?
You could look at the desired method and use reflection to pull out whatever info you want. Modify this and the object class hold whatever you want it to.
public class DiscoverInternalClass
{
public List<InternalClassObject> FindClassMethods(Type type)
{
List<InternalClassObject> MethodList = new List<InternalClassObject>();
MethodInfo[] methodInfo = type.GetMethods();
foreach (MethodInfo m in methodInfo)
{
List<string> propTypeList = new List<string>();
List<string> propNameList = new List<string>();
string returntype = m.ReturnType.ToString();
foreach (var x in m.GetParameters())
{
propTypeList.Add(x.ParameterType.Name);
propNameList.Add(x.Name);
}
InternalClassObject ICO = new InternalClassObject(c.Name, propNameList, propTypeList);
MethodList.Add(ICO);
}
return MethodList;
}
}
he object class could be something like this or modify it however you want:
public class InternalClassObject
{
public string Name { get; set; }
public List<string> ParameterNameList { get; set; }
public List<string> ParameterList { get; set; }
public InternalClassObject(string iName,List<string> iParameterNameList, List<string> iParameterList)
{
Name = iName;
ParameterNameList = iParameterNameList;
ParameterList = iParameterList;
}
}
You could call the method like this with the desired class.
public static List<InternalClassObject> MethodList = new List<InternalClassObject>();
DiscoverInternalClass newDiscover= new DiscoverInternalClass();
MethodList = newDiscover.FindClassMethods(typeof(ExtendedDocumentViewModel));
Now you can have your GetView build based on what is in MethodList
Hope this helps!
I have a little design problem. Let's say I have a project that contains a large number of people. I want to allow the user to export those people to a CSV file with the information he chooses.
For example, He could choose Id, Name, Phone number and according to his choice I would create the file.
Of course, there is a simple of way doing it like if(idCheckBox.Checked) getId(); etc.
I'm looking for something better. I don't want that for each new option I would like to add I would need to change the UI (e.g. New checkbox).
I thought of reading the possible options from a file, but that will only solved the UI problem. How would I know which values to get without using all those "if's" again?
You don't need a fancy design pattern for this task. However I understand you have identified a reason to change (added options in future). So you want to minimize amount of classes to be modified.
Your real problem is how to decouple CSV creation from the objects whose structure is going to change. You don't want your parsing logic to be affected whenever your Person class is changed.
In the following example the CSV object is truly decoupled from the objects it receives and parses. To achieve this, we are coding to an abstraction rather to an implementation. This way we are not even coupled to the Person object, but will welcome any objects that implement the AttributedObject interface. This dependency is being injected to our CSV parser.
I implemented this in PHP, but the idea is the same. C# is a static language, so fetching the attributes would be with a bit of change. You might use some kind of ArrayAccess interface.
interface AttributedObject {
public function getAttribute($attribute);
}
class Person implements AttributedObject {
protected $firstName;
protected $lastName;
protected $age;
protected $IQ;
public function __construct($firstName, $lastName, $age, $IQ)
{
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->age = $age;
$this->IQ = $IQ;
}
public function getAttribute($attribute)
{
if(property_exists($this, $attribute)) {
return $this->$attribute;
}
throw new \Exception("Invalid attribute");
}
}
class CSV {
protected $attributedObject = null;
protected $attributesToDisplay = null;
protected $csvRepresentation = null;
protected $delimiter = null;
public function __construct(AttributedObject $attributedObject, array $attributesToDisplay, $delimiter = '|')
{
$this->attributedObject = $attributedObject;
$this->attributesToDisplay = $attributesToDisplay;
$this->delimiter = $delimiter;
$this->generateCSV();
}
protected function generateCSV()
{
$tempCSV = null;
foreach ($this->attributesToDisplay as $attribute) {
$tempCSV[] = $this->attributedObject->getAttribute($attribute);
}
$this->csvRepresentation = $tempCSV;
}
public function storeCSV()
{
$file = fopen("tmp.csv", "w");
fputcsv($file, $this->csvRepresentation, $this->delimiter);
}
}
$person1 = new Person('John', 'Doe', 30, 0);
$csv = new CSV($person1, array('firstName', 'age', 'IQ'));
$csv->storeCSV();
You can build a mapping set of fields based what fields the user is allowed to select, and which fields are required. This data can be read from a file or database. Your import/export can be as flexible as needed.
Here is a conceivable data structure that could hold info for your import/export sets.
public class FieldDefinition
{
public FieldDataTypeEnum DataType { get; set; }
public string FieldName{get;set;}
public int MaxSize { get; set; }
public bool Required { get; set; }
public bool AllowNull { get; set; }
public int FieldIndex { get; set; }
public bool CompositeKey { get; set; }
}
public class BaseImportSet
{
private List<FieldDefinition> FieldDefinitions { get; set; }
protected virtual void PerformImportRecord(Fields selectedfields)
{
throw new ConfigurationException("Import set is not properly configured to import record.");
}
protected virtual void PerformExportRecord(Fields selectedfields)
{
throw new ConfigurationException("Export set is not properly configured to import record.");
}
public LoadFieldDefinitionsFromFile(string filename)
{
//Implement reading from file
}
}
public class UserImportSet : BaseImportSet
{
public override void PerformImportRecord(Fields selectedfields)
{
//read in data one record at a time based on a loop in base class
}
public override string PerformExportRecord(Fields selectedfields)
{
//read out data one record at a time based on a loop in base class
}
}
I've been doing a lot of research on different design patterns and I'm trying to determine the correct way of doing this.
I have an image uploading MVC app that I'm developing which needs to process the image in several different ways, such as create a thumbnail and save a database record. Would the best way to approach this be via a flyweight pattern? Using this as an example:
var image = new Image();
List<IProcessors> processors = processorFactory.GetProcessors(ImageType.Jpeg);
foreach(IProcessor processor in processors)
{
processor.process(image);
}
I have second part to this question as well. What if the processor has smaller related "sub-processors"? An example that I have in my head would be a book generator.
I have a book generator
that has page generators
that has paragraph generators
that has sentence generators
Would this be a flyweight pattern as well? How would I handle the traversal of that tree?
EDIT
I asked this question below but I wanted to add it here:
All the examples that I've see of the composite pattern seems to relate to handling of values while the flyweight pattern seems to deal with processing (or sharing) of an object's state. Am I just reading into the examples too much? Would combining the patterns be the solution?
I can at least handle the second part of the question. To expand a tree (or a composite), use simple recursion.
void Recursion(TreeItem parent)
{
// First call the same function for all the children.
// This will take us all the way to the bottom of the tree.
// The foreach loop won't execute when we're at the bottom.
foreach (TreeItem child in parent.Children)
{
Recursion(child);
}
// When there are no more children (since we're at the bottom)
// then finally perform the task you want. This will slowly work
// it's way up the entire tree from bottom most items to the top.
Console.WriteLine(parent.Name);
}
What your describing could have some flyweights representing each of those nested classes. But in this case that would be more of an implementation detail. In my experience, flyweights are usually called for at the architectural level or implementation level but rarely as an element of design.
Consider this class -
public interface IMyData {
IdType MyId { get; }
byte[] BlobData { get; }
long SizeOfBlob { get; }
}
public class MyData : IMyData {
public IdType MyId { get; private set; }
public byte[] BlobData { get; set; }
public long SizeOfBlob { get { return BlobData.LongLength; } }
}
}
In your multi-tiered application, this object needs to travel from the source database, to a manager's IPhone for approval based on the blob size, and then to an accounting system for billing. So instead of transporting the whole thing to the IPhone App, you substitute the flyweight:
public class MyDataFlyWeight : IMyData {
public MyDataFlyWeight(IdType myId, long blobSize){
MyId = myId;
BlobSize = blobSize;
}
public IdType MyId { get; set; }
public byte[] MutableBlobData { get {
throw new NotImplmentedException();
}
}
public long BlobSize { get; private set; }
}
}
By having both implement IMyData and by building the system with the interface and not the concrete type (you did this, right?!), then you could use MyDataFlyweight objects from the IPhone App and MyData objects in the rest of the system. All you have to do is properly initialize MyDataFlyweight with the blob size.
The architecture which calls for an IPhone App would dictate that a flyweight is used within the IPhone App.
In addition, consider the newer Lazy<T> class:
public class MyData : IMyData {
public IdType MyId { get; private set; }
private Lazy<byte[]> _blob = new Lazy<byte[]>(() =>
StaticBlobService.GetBlob(MyId));
public byte[] BlobData { get { return _blob.Value; } }
public long SizeOfBlob { get { return BlobData.LongLength; } }
}
}
This is an example of using the flyweight purely as an implementation detail.
I'm working on a web service that needs to accept a collection with three values of different types. The values are
SkuNumber (integer),
FirstName (string),
LastName (string)
I want the web service to accept a list of 100 instances of these values but am not sure how to go about it. Do I use a multidimensional list or array? Maybe a tuple? Or can I just create a simple class structure and accept a list of that class?
This is all simple enough in a normal application, I'm just not sure how the app calling the web service would pass the data with any of the given options.
Can someone give me some pointers?
If a shared assembly is not feasible, you can always go with good ol' XML. It may not be the optimal solution and I'm sure plenty of users here will balk at the idea, but it is easy to support and relatively quick to implement, so it really depends on your individual situation and the skill level of the developers responsible for supporting the application.
The benefit to using XML here, is that the calling application can be written in almost any language on almost any platform, as long as it adheres to the XML structure.
The XML string should be easy enough to generate in the calling application, but the biggest downside here is that if you have a ton of data, the processing may take longer than desired -- on both ends of the service.
Here is a working sample if you want to give it a try:
public class Whatever
{
public int SkuNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
[WebMethod]
public void HelloWorld(string xmlString)
{
//make all the node names + attribute names lowercase, to account for erroneous xml formatting -- leave the values alone though
xmlString = Regex.Replace(xmlString, #"<[^<>]+>", m => m.Value.ToLower(),RegexOptions.Multiline | RegexOptions.Singleline);
var xmlDoc = LoadXmlDocument(xmlString);
var listOfStuff = new List<Whatever>();
var rootNode = xmlDoc.DocumentElement;
foreach(XmlNode xmlNode in rootNode)
{
var whatever = new Whatever
{
FirstName = xmlNode["first_name"].InnerText,
LastName = xmlNode["last_name"].InnerText,
SkuNumber = Convert.ToInt32(xmlNode["sku_number"].InnerText)
};
listOfStuff.Add(whatever);
}
}
public static XmlDocument LoadXmlDocument(string xmlString)
{
//some extra stuff to account for URLEncoded strings, if necessary
if (xmlString.IndexOf("%3e%") > -1)
xmlString = HttpUtility.UrlDecode(xmlString);
xmlString = xmlString.Replace((char)34, '\'').Replace("&", "&").Replace("\\", "");
var xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = false;
xmlDocument.LoadXml(xmlString);
return xmlDocument;
}
Your XML would look like this:
<stuff_to_track>
<whatever>
<sku_number>1</sku_number>
<first_name>jimi</first_name>
<last_name>hendrix</last_name>
</whatever>
<whatever>
<sku_number>2</sku_number>
<first_name>miles</first_name>
<last_name>davis</last_name>
</whatever>
<whatever>
<sku_number>3</sku_number>
<first_name>david</first_name>
<last_name>sanborn</last_name>
</whatever>
<whatever>
<sku_number>4</sku_number>
<first_name>john</first_name>
<last_name>coltrane</last_name>
</whatever>
</stuff_to_track>
I also recommend validating the incoming XML, for both schema and data.
Create a class and accept a list of that class. Be sure to mark it as [Serializable].
[Serializable]
public class Whatever
{
public int SkuNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Best practice would be to define the class in an assembly that can be accessed by both the service and the project that calls it.
The trouble with a tuple or a multi-dimensional array is that the data you send doesn't have an inherent identity: you could stick any old thing in there. If you have a class, you are indicating that you are sending an Order or an Inquiry or a Coupon or whatever it is you are tracking. There's a level of meaning that goes along with it.
Just send what you want:
public class Whatever
{
public int SkuNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
[WebMethod]
public void TakeList(List<Whatever> theList)
{
foreach (var w in theList)
{
}
}
The basic goal is to create a Business Card for each contact and put that card in a FlowLayoutPanel. The card itself is comprised of about 10 labels and 3 comboboboxes.
It doesn't take too many business cards to cause initial population of the panel to take a long time. Maybe I can find a way to deal with this
However, a primary concern is crashing. It only takes about 200 or so cards to crash (run out of handles).
I agree there are paging methods that could be implemented since a user never will need to see more than will fit on 1 or 2 screens at a time, but writing paging routines might be pretty tough.
Any suggestions on how to maximize efficiency of this planned FlowLayoutPanel?
P.S. The main issue is running out of handles (too many controls in the panel). Must resolve this before worrying about speed.
Okay, how about:
Create a class to store the information necessary to recreate a business card (10 labels and 3 comboboboxes) as public, gettable/settable properties, and with an empty default public constructor. Then, serialize each business card as an xml (or binary) file using XmlSerializer into a single folder. Then, you could use something like string[] businessCards = Directory.GetFiles(Path.GetFullPath("mysettings\\businesscards")); to iterate through your long 'cached' list of business cards. Have class that manages adding/removing items from your FlowLayoutPanel by calling a function like: SerializableBusinessCardClass GetNextCard() {}. This would be fairly simple to implement. You could also serialize a List<SerializableBusinessCardClass> with a length of about 5 (or however many you wanted to load in at once) to a single XML file for maximum efficiency, or if you have a truly ridiculous amount of business cards (such that explorer lags when browsing the folder). While a binary serialization would be faster, the XML approach has the added benefit that your clients can specify new business cards they want you to display by creating the XML file yourself.
Here, I will give you a concrete example of how you would build and serialize such a data structure:
public class SerializableBusinessCard
{
public SerializableBusinessCard() { }
public string Name { get; set; }
public string Company { get; set; }
public List<string> Labels { get; set; }
public List<ComboItem> ComboBoxes { get; set; }
}
public class ComboItem
{
public ComboItem() { }
public string Name { get; set; }
public string Text { get; set; }
public int SelectedIndex { get; set; }
public Point Location { get; set; }
public Size size { get; set; }
public List<string> Collection{ get; set; }
}
Usage:
public void stackoverflow_BusinessCard_FlowLayoutPanel()
{
List<string> labels = new List<string>();
labels.Add("Title");
labels.Add("Description");
labels.Add("Phone");
labels.Add("Email");
labels.Add("Address");
labels.Add("label6");
labels.Add("labelN");
ComboItem cItem = new ComboItem();
cItem.Collection = new List<string>();
cItem.Collection.Add("Option1");
cItem.Collection.Add("Option2");
cItem.Name = "comboName";
cItem.SelectedIndex = 0;
cItem.Text = cItem.Collection[cItem.SelectedIndex];
cItem.Location = new Point(50, 265);
cItem.size = new Size(100,21);
List<ComboItem> comboItems = new List<ComboItem>();
comboItems.Add(cItem);
SerializableBusinessCard bCard1 = new SerializableBusinessCard();
bCard1.Name = "CompanyXYZ_BlueTheme";
bCard1.Company = "CompanyXYZ";
bCard1.Labels = labels;
bCard1.ComboBoxes = comboItems;
SerializeObjectXML("BusinessCard_392.xml",bCard1);
SerializableBusinessCard loaded = DeserializeBusinessCardXML("BusinessCard_392.xml");
}
Here is the serialization function:
public void SerializeObjectXML(string filename,object obj)
{
using(StreamWriter streamWriter = new StreamWriter(filename))
{
XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
xmlSerializer.Serialize(streamWriter,obj);
}
}
Result:
<?xml version="1.0" encoding="utf-8"?>
<SerializableBusinessCard xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>CompanyXYZ_BlueTheme</Name>
<Company>CompanyXYZ</Company>
<Labels>
<string>Title</string>
<string>Description</string>
<string>Phone</string>
<string>Email</string>
<string>Address</string>
<string>label6</string>
<string>labelN</string>
</Labels>
<ComboBoxes>
<ComboItem>
<Name>comboName</Name>
<Text>Option1</Text>
<SelectedIndex>0</SelectedIndex>
<Location>
<X>50</X>
<Y>265</Y>
</Location>
<size>
<Width>100</Width>
<Height>21</Height>
</size>
<Collection>
<string>Option1</string>
<string>Option2</string>
</Collection>
</ComboItem>
</ComboBoxes>
</SerializableBusinessCard>
And the deserializer:
public static SerializableBusinessCard DeserializeBusinessCardXML(string filename)
{
SerializableBusinessCard result = new SerializableBusinessCard();
using(StreamReader streamReader = new StreamReader(filename))
{
XmlSerializer xmlReader = new XmlSerializer(typeof(SerializableBusinessCard));
result = (SerializableBusinessCard) xmlReader.Deserialize(streamReader);
}
return result;
}
Hope this helps.