المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : Trouble deleting items using generic xml provider.



C# Programming
02-19-2010, 10:42 AM
Hi folks,

Firstly, I apologise for the length of this question, The classes I'm working with are quite complicated so I didn't want to ask a question without giving you a decent idea of what you are looking at.

I've been working all day on a specialized XML provider for use as a datastore on websites.

The idea is that I can use the same provider to serialize and deserialize any classes that I initialize the provider with so that everything is strong typed.

eg If I want to initialize a provider for a Person class I just say:

XmlProvider xp = new XmlProvider(directory, fileName);
If I want to initialize a provider for a Client class I just say:

XmlProvider xp = new XmlProvider(directory, fileName);
This has been all going well, I can add a serialized class instance and update values but not delete them.

Here's what's going on in my provider class.

//-----------------------------------------------------------------------
//
// Copyright (c) Empirical Design. All rights reserved.
//
//-----------------------------------------------------------------------
namespace XmlProviders
{
#region Using
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
using System.Reflection;
#endregion
/// /// A specialized generic provider that uses an xml file to store its data.
/// /// class or struct with all the data-fields that must be persisted. public class XmlProvider where T : new()
{
#region Fields

/// /// Our object to lock against.
/// private object syncRoot = new object();

/// /// The virtual path to our datastore.
/// private string path;

/// /// The filename of the datastore.
/// private string fileName;

/// /// The weak reference to our store.
/// private WeakReference storeRef;

/// /// The full physical filepath to our datastore
/// private string fullFilePath;
#endregion
#region Constructors

/// /// Initializes a new instance of the XmlProvider class.
/// /// The virtaul path to the datastore. /// The filename of the datastore. public XmlProvider(string path, string fileName)
{
this.Path = path;
this.FileName = fileName;
this.fullFilePath = MapPath(string.Format("{0}//{1}", this.Path, this.FileName));
}
#endregion
#region Properties

/// /// Gets or sets the directory path.
/// /// The directory path for the datastore. public string Path
{
get {
EnsureDataFolder(this.path);

return this.path;
}

set {
if (value.IndexOf("~/") == -1)
{
value = string.Format("~/{0}", value);

this.path = value;
}

this.path = value;
}
}

/// /// Gets or sets the filename.
/// /// The filename of the datastore. public string FileName
{
get {
return this.fileName;
}
set {
if (value.IndexOf(".") == -1)
{
value = String.Format("{0}.xml", value.ToLowerInvariant());
this.fileName = value;
}
else {
value = String.Format("{0}.xml", value.Substring(0, value.IndexOf(".")).ToLowerInvariant());
this.fileName = value;
}
}
}

/// /// Gets the sync root.
/// /// The sync root. protected internal object SyncRoot
{
get { return this.syncRoot; }
}

/// /// Gets the role store.
/// /// The role store. private XmlStore Store
{
get {
XmlStore store = this.StoreRef.Target as XmlStore;

if (store == null)
{
this.StoreRef.Target = store = new XmlStore(this.fullFilePath);
}

return store;
}
}

/// /// Gets the store ref.
/// /// The store ref. private WeakReference StoreRef
{
get {
return this.storeRef ?? (this.storeRef = new WeakReference(new XmlStore(this.fullFilePath)));
}
}

#endregion
#region Methods

/// /// Gets a list of all the generic objects from the datasource from the datstore.
/// /// A strongly typed list of all the generic objects from the datstore. public List GetAllElements()
{
lock (this.SyncRoot)
{
return (this.Store.Items != null) ? this.Store.Items : null;
}
}

/// /// Creates a new generic object in the datastore.
/// /// The object to add to the list. public void CreateItem(T item)
{

if (item.GetType() != typeof(T))
{
throw new ArgumentException("The specified type does not match the type initialized by the provider.");
}
if (ItemExists(item))
{
throw new ArgumentException("An object matching the specified object already exists.");
}
try {
lock (this.SyncRoot)
{
this.Store.Items.Add(item);
this.Store.Save();
}
}
catch {
throw;
}
}

/// /// Updates the generic object to the datastore.
/// /// The original obect to update. /// The updated object. public void UpdateItem(T originalItem, T newItem)
{
if (originalItem.GetType() != typeof(T) | newItem.GetType() != typeof(T))
{
throw new ArgumentException("The specified types do not match the type initialized by the provider.");
}

lock (this.SyncRoot)
{
T t = this.GetItem(originalItem);
if (t != null)
{

try {
Array.ForEach(newItem.GetType().GetProperties(), p => Array.ForEach(t.GetType().GetProperties(), p2 =>
{
if (p.Name == p2.Name)
p.SetValue(t, p2.GetValue(newItem, null), null);
}));

this.Store.Save();
}
catch {
throw;
}

}
}
}

/// /// Deletes the generic object from the datastore.
/// /// The generic object to delete. public void DeleteItem(T item)
{
try {
lock (SyncRoot)
{
T t = this.GetItem(item);
if (t != null)
{
this.Store.Items.Remove(t);
this.Store.Save();
}
}
}

catch {
throw;
}


}

/// /// Gets the specified object from the datastore.
/// /// The object to search for. /// The stored version of the specified object. private T GetItem(T item)
{

lock (SyncRoot)
{
return (this.Store.Items != null) ? this.Store.Items.Find((T t) => t.Equals(item)) : default(T);
}

}

/// /// Check to see whether our generic object already exists in the datastore.
/// /// The object to check for. /// true if the object exists; otherwise, false. public bool ItemExists(T item)
{
lock (this.SyncRoot)
{
if (this.Store.Items.Contains(item))
{
return true;
}

}

return false;
}

/// /// Ensures that the specified folder is present by creating one if not.
/// /// The folder to check against. private static void EnsureDataFolder(string strFolder)
{
if (HttpContext.Current != null)
{
if (!Directory.Exists(strFolder))
{
try {
strFolder = HostingEnvironment.MapPath(strFolder);
Directory.CreateDirectory(strFolder);
}
catch {
throw new IOException("Unable to create directory. Check read/write access for root.");
}
}
}
}

/// /// Maps a virtual path to a physical path on the server.
/// /// The virtual path to map. /// The the physical path on the server. private static string MapPath(string virtualPath)
{
return HostingEnvironment.MapPath(virtualPath);
}

#endregion }
}

And in my store class.


//-----------------------------------------------------------------------
//
// Copyright (c) Empirical Design. All rights reserved.
//
//-----------------------------------------------------------------------
namespace XmlProviders
{
#region Using
using System;
using System.Collections.Generic;
#endregion
/// /// A store for lists of generic types.
/// /// class or struct with all the data-fields that must be persisted. internal class XmlStore : Persistable
{
/// /// Initializes a new instance of the XmlStore class. Also creates a instance of T
/// /// The filename of the datastore to persist. /// /// Initializes a new instance of the XmlList class. Also creates a instance of T
/// /// The filename of the datastore to persist. internal XmlStore(string fileName)
: base(fileName){
}

/// /// Initializes a new instance of the class. Also creates a instance of T
/// internal XmlStore()
: base(null){
}

#region "Properties"
/// /// Gets a list of the generic type entries.
/// /// The generic type entries. internal List Items
{
get { return base.Value ?? (base.Value = new List()); }
}

#endregion }
}

The persistable class is basically a generic serializer. I can post it if anyone wants to have a look.

Whenever I call my DeleteItem routine, the Store reference is not removing the item from my list. I can't figure out why. Perhaps I am missing something simple.

Any advice would be handy.

Many thanks.JimBob SquarePants
*******************************************************************
"He took everything personally, including our royalties!"
David St.Hubbins, Spinal Tap about Ian Faith, their ex-manager
*******************************************************************