Reputation: 768
I am trying to move some C#
MVC legacy code into a shared DLL. All went well so far, but I was asked that that shared DLL need not reference System.Web
in any way.
The only type used in that DLL from System.Web is HttpPostedFileBase
:
public string ChangeAttachment(int userId, HttpPostedFileBase file)
{
string attachmentsFolderPath = ConfigurationManager.AppSettings["AttachmentsDirectory"];
if (!Directory.Exists(attachmentsFolderPath))
{
Directory.CreateDirectory(attachmentsFolderPath);
}
string fileTarget = Path.Combine(attachmentsFolderPath, userId.ToString() + Path.GetExtension(file.FileName));
if (File.Exists(fileTarget))
{
File.Delete(fileTarget);
}
file.SaveAs(fileTarget);
return fileTarget;
}
As you can see, no HTTP or Web functionality is needed here, as only its FileName
and SaveAs()
members are used.
Is there a substitute that I can easily convert HttpPostedFileBase
to it at the caller, so that all I need to pass as a parameter is a non-web file?
Note: HttpPostedFileBase
inherits directly from System.Object
, not from any file class.
Upvotes: 3
Views: 1235
Reputation: 5137
If you don't want to Reference System.Web
and also want to use the SaveAs method, you can define an interface and also a wrapper to make a link. It's not a very simple approach though:
//// Second assembly (Without referencing System.Web):
// An interface to link the assemblies without referencing to System.Web
public interface IAttachmentFile {
void SaveAs(string FileName);
}
..
..
// Define ChangeAttachment method
public string ChangeAttachment(int userId, IAttachmentFile attachmentFile) {
string attachmentsFolderPath = ConfigurationManager.AppSettings["AttachmentsDirectory"];
if (!Directory.Exists(attachmentsFolderPath)) {
Directory.CreateDirectory(attachmentsFolderPath);
}
string fileTarget = Path.Combine(
attachmentsFolderPath,
userId.ToString() + Path.GetExtension(file.FileName)
);
if (File.Exists(fileTarget)) {
File.Delete(fileTarget);
}
// This call leads to calling HttpPostedFileBase.SaveAs
attachmentFile.SaveAs(fileTarget);
return fileTarget;
}
//// First assembly (Referencing System.Web):
// A wrapper class around HttpPostedFileBase to implement IAttachmentFile
class AttachmentFile : IAttachmentFile {
private readonly HttpPostedFileBase httpPostedFile;
public AttachmentFile(HttpPostedFileBase httpPostedFile) {
if (httpPostedFile == null) {
throw new ArgumentNullException("httpPostedFile");
}
this.httpPostedFile = httpPostedFile;
}
// Implement IAttachmentFile interface
public SaveAs(string fileName) {
this.httpPostedFile.SaveAs(fileName);
}
}
..
..
// Create a wrapper around the HttpPostedFileBase object
var attachmentFile = new AttachmentFile(httpPostedFile);
// Call the ChangeAttachment method
userManagerObject.ChangeAttachment(userId, attachmentFile);
Upvotes: 1
Reputation: 29222
HttpPostedFileBase
is an abstract class. So the challenge is that you're not actually replacing that class, you're replacing HttpPostedFileWrapper
, which is the implementation. (It's not what the class inherits from, it's what inherits from it.)
HttpPostedFileWrapper
in turn references other System.Web
classes like HttpInputStream
and 'HttpPostedFile`.
So you can't replace it. Perhaps by asking you not to reference System.Web the intent was that you were moving legacy code not directly related to web functionality, like business logic. If you can't just leave the code out altogether, perhaps you could leave it out of the new assembly you're creating, and then have another assembly which does reference System.Web
. If they don't need this particular functionality they only reference the one assembly, but if they need this then they can also add the second assembly which does reference System.Web
.
Upvotes: 4