I am making a gallery tool that lets you browse and edit objects. I have a 'Library' class that manages the fetching and displaying of the gallery list. I also have an 'ActiveItem' asset that loads all the information of the selected object and deals with modifying it.
Now, there's some information that is stored in the 'library' class (for example the filepath) that I want to use in my activeitem.
I'm a bit confused as to how I can set this up efficiently.
I thought about embedding the activeitem class in the library class, but it gets a bit annoying to have to access all functions and properties of the activeitem through the library class (so instead of writing activeitem.Load() I would have to write lib.activeitem.Load() ). Activeitem already goes 4 levels deep and it's getting a bit much.
Are there other ways of setting this up? Can I store a reference of the library class instance inside the activeitem class, so that the activeitem class can fetch a property of the library instance?
Edit: added some code snippets
This are the class definitions:
class Library
{
...
public string LibDirectory;
...
}
class ActiveAsset
{
...
public SaveAsset()
{
//this method needs to know the LibDirectory property of the libraryclass
}
}
On initiating my winform, I initiate both classes:
Library lib = new Library();
ActiveAsset activeAsset = new ActiveAsset();
Given the concerns in the question comments, if you want ActiveAsset to be able to read information from Library you could change ActiveAsset's constructor to take in Library and store it internally as a private var.
class ActiveAsset
{
private Library _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
If you are worried about design and coupling you could make in interface for Library and then make the constructor use that instead of the Library class
interface ILibrary {
string LibDir { get; set; }
}
class Library : ILibrary {
}
class ActiveAsset
{
private ILibrary _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
As for performance and creating deep levels of nested classes I don't think you will have to worry so much about it, chances are you will hit data save/retrieve performance issues before anything like too many classes. That kind of performance design is only really important when you try to make you code work on small platforms where memory is limited like rasberryPi and such.
I would suggest creating a wrapper class which holds both the Library and the ActiveItem instances. Thus you can have more generalised methods like:
GetAllItems() - gets all items from the library
ActivateItem(Item item) - activates the item provided (stores the given item to a variable in the wrapper class)
etc. Think of that wrapper class as the manager of your application. You would only like to work with that manager regardless of what's beneath it.
Related
Imagine the following scenario in a Xamarin solution:
Assembly A (PCL):
public abstract class MyBaseClass
{
public MyBaseClass()
{
[...]
}
[...]
}
Assembly B (3rd Party Library):
public class SomeLibClass
{
[...]
public void MethodThatCreatesClass(Type classType){
[...]
//I want to allow this to work
var obj = Activator.CreateInstance(classType);
[...]
}
[...]
}
Assembly C (Main project):
public class ClassImplA:MyBaseClass{
[...]
}
public class ClassImplA:MyBaseClass{
[...]
}
public class TheProblem{
public void AnExample(){
[...]
//I want to block these instantiations for this Assembly and any other with subclasses of MyBaseClass
var obj1 = new ClassImplA()
var obj2 = new ClassImplB()
[...]
}
}
How can I prevent the subclasses from being instantiated on their own assembly and allow them only on the super class and the 3rd Party Library (using Activator.CreateInstance)?
Attempt 1
I though I could make the base class with an internal constructor but then, I saw how silly that was because the subclasses wouldn't be able to inherit the constructor and so they wouldn't be able to inherit from the superclass.
Attempt 2
I tried using Assembly.GetCallingAssembly on the base class, but that is not available on PCL projects. The solution I found was to call it through reflection but it also didn't work since the result of that on the base class would be the Assembly C for both cases (and I think that's because who calls the constructor of MyBaseClass is indeed the default constructors of ClassImplA and ClassImplB for both cases).
Any other idea of how to do this? Or am I missing something here?
Update
The idea is to have the the PCL assembly abstract the main project (and some other projects) from offline synchronization.
Given that, my PCL uses its own DB for caching and what I want is to provide only a single instance for each record of the DB (so that when a property changes, all assigned variables will have that value and I can ensure that since no one on the main project will be able to create those classes and they will be provided to the variables by a manager class which will handle the single instantions).
Since I'm using SQLite-net for that and since it requires each instance to have an empty constructor, I need a way to only allow the SQLite and the PCL assemblies to create those subclasses declared on the main project(s) assembly(ies)
Update 2
I have no problem if the solution to this can be bypassed with Reflection because my main focus is to prevent people of doing new ClassImplA on the main project by simple mistake. However if possible I would like to have that so that stuff like JsonConvert.DeserializeObject<ClassImplA> would in fact fail with an exception.
I may be wrong but none of the access modifiers will allow you to express such constraints - they restrict what other entities can see, but once they see it, they can use it.
You may try to use StackTrace class inside the base class's constructor to check who is calling it:
public class Base
{
public Base()
{
Console.WriteLine(
new StackTrace()
.GetFrame(1)
.GetMethod()
.DeclaringType
.Assembly
.FullName);
}
}
public class Derived : Base
{
public Derived() { }
}
With a bit of special cases handling it will probably work with Activator class , but isn't the best solution for obvious reasons (reflection, error-prone string/assembly handling).
Or you may use some dependency that is required to do anything of substance, and that dependency can only be provided by your main assembly:
public interface ICritical
{
// Required to do any real job
IntPtr CriticalHandle { get; }
}
public class Base
{
public Base(ICritical critical)
{
if (!(critical is MyOnlyTrueImplementation))
throw ...
}
}
public class Derived : Base
{
// They can't have a constructor without ICritical and you can check that you are getting you own ICritical implementation.
public Derived(ICritical critical) : base(critical)
{ }
}
Well, other assemblies may provide their implementations of ICritical, but yours is the only one that will do any good.
Don't try to prevent entity creation - make it impossible to use entities created in improper way.
Assuming that you can control all classes that produce and consume such entities, you can make sure that only properly created entities can be used.
It can be a primitive entity tracking mechanism, or even some dynamic proxy wrapping
public class Context : IDisposable
{
private HashSet<Object> _entities;
public TEntity Create<TEntity>()
{
var entity = ThirdPartyLib.Create(typeof(TEntity));
_entities.Add(entity);
return entity;
}
public void Save<TEntity>(TEntity entity)
{
if (!_entities.Contains(entity))
throw new InvalidOperationException();
...;
}
}
It won't help to prevent all errors, but any attempt to persist "illegal" entities will blow up in the face, clearly indicating that one is doing something wrong.
Just document it as a system particularity and leave it as it is.
One can't always create a non-leaky abstraction (actually one basically never can). And in this case it seems that solving this problem is either nontrivial, or bad for performance, or both at the same time.
So instead of brooding on those issues, we can just document that all entities should be created through the special classes. Directly instantiated objects are not guaranteed to work correctly with the rest of the system.
It may look bad, but take, for example, Entity Framework with its gotchas in Lazy-Loading, proxy objects, detached entities and so on. And that is a well-known mature library.
I don't argue that you shouldn't try something better, but that is still an option you can always resort to.
'm trying to design a system where a class would be defined in a project, be referenced in another and have new functionalities in the latter. Is there a pattern for this?
Context: I have a game that has items in a common project. Both the server and client reference this same project so I can have the item StaffItem in both the server and client, making it easier to serialize and deserialize between the two. The problem is, I can't redefine the StaffItem class in the client, since it will change the server's perspective of this class. I'm trying to find a nice way to add, for instance, the rendering to the client-side view of the class (added code for textures and all that).
I'm almost at the point of giving up and simply putting the rendering code in the common project, and stubbing it for the server. Any pointers (hehe) would be appreciated.
Instead of transferring the actual objects over the wire, you could introduce a DTO class for serializing and deserializing. This decouples the actual implementations on both sides.
If I understand your question right, there are two options you may consider. First one is to use smth similar with decorator pattern:
class StaffItem : IStaffItem {
public int MyProp {get;set;}
public void MyAction() {}
}
class ClientStaffItem : IStaffItem {
private StaffItem _staffItem;
public ClientStaffItem(StaffItem staffItem) {
_staffItem = staffItem;
}
public int MyProp {
get { return _staffItem.MyProp;}
set {_staffItem.MyProp; = value;}
}
public void MyAction() {
_staffItem.MyAction();
}
public void YouClientMethod() {}
}
The other one use inheritance, but determine which fields you need to serialize and how and use attributes or custom serialization settings to mark only properties you need.
I'm writing a CAD program. Let's say I have in input class, this class reads various data from a text file and creates lots of lists/dictionaries and .... These data need to be accessed by other methods in other classes to be modified. Now here is how I have done it so far:
I have one static class: Building.cs When I create/or load a project this class holds all the data like list of columns, beams, points, etc. All of these are stored as private fields. I can access these using the class's public methods like GetColumns or GetPoints ...
Now I also have non-static classes. They contain 2-3 public methods. and do some stuff on various parts of the building.
public static class Building
{
private static List<Column> columns;
private static List<Beams> beams;
private static List<Points> points;
public static List<Column> GetColumns()
{
return Columns;
}
}
public class ColumnsService()
{
private List<Columns> columns;
public GroupColumns(List<Columns> columns)
{
this.columns = columns;
}
public void Group()
{
// group columns
}
}
var columns = Building.GetColumns();
var columnsService = new ColumnsService(columns);
columnsService.Group();
I was wondering is this the way to go? How else can I store the data. The data needs to be accessible throughout the lifetime of the program to most of the classes. What are the best practices.
What, semantically, is a Building?
To me, the name implies that it's an instance of a structure. That, in the overall business domain, there can be many "buildings" and at any given moment one is interacting with one of them.
If that's the case, then it seems unintuitive to me to make it static. If there's more than one, it should be an instance model. It would contain attributes which describe it and operations which interact with it. The business domain being modeled should drive the structure of this object before any consideration is given to how other objects are going to interact with it.
So let's assume we make it an instance model:
public class Building
{
// attributes and operations
}
Then, as you ask, how do other objects interact with it?
Depends on the interactions.
Let's say an object needs to "render" a building in some way. Let's call it BuildingPrinter for lack of a better term. Clearly it needs a Building to "print". So it requires one for that operation:
public class BuildingPrinter
{
public void Print(Building building)
{
// implementation
}
}
Or perhaps you have an object which "wraps" a building in some way. Something which can't meaningfully exist without a building, regardless of the operations performed. I can't think of one for that particular business domain, so let's just call it a BuildingWidget. Since it needs a building to exist at all, it requires one:
public class BuildingWidget
{
private Building currentBuilding;
private BuildingWidget() { }
public BuildingWidget(Building building)
{
currentBuilding = building;
}
}
The point is, from the perspective of the models which construct the overall domain, if something is required then it must be supplied. The models shouldn't go out to some global data store, tightly coupling with that data store, to get what they need. This is called the Dependency Inversion Principle.
But where will the consuming code which orchestrates the interactions of these models get instances of a Building? There are a number of potential solutions to that.
Two common patterns would be to have a static factory or a repository. For example:
public class BuildingFactory
{
public static Building FetchBuilding(int buildingId)
{
// implementation
}
}
This factory might have a static cached building object. The building itself isn't static, but for performance reasons an instance of it is cached statically so that it's not constantly re-fetched from a backing data store (such as a database). You might also add methods to invalidate the cache and re-fetch, or encapsulate that logic into the factory itself (such as always re-fetch after 5 minutes or after 10 accesses or some other rule). (Behind the scenes, this factory might even use a repository, shown below, to re-fetch that instance. In which case, you guessed it, a BuildingRepository would be required on the BuildingFactory constructor.)
This factory object may also be responsible for creating a building based on some specifications, if for example you have reason to make the Building constructor private.
Or, to re-fetch from data, consider a repository:
public class BuildingRepository
{
public Building GetBuilding(int buildingId)
{
// fetch from database
}
public Building SaveBuilding(Building building)
{
// save to database, return updated version
}
}
Then other code throughout the domain, including the consuming code, can use these objects to get/save buildings. The factory is static, so that can be invoked anywhere. The repository is instance but doesn't need to be globally distinct, so that can be instantiated anywhere (or pulled form a dependency injection container).
Given a basic C# library, how do I implement functions of this library into my WPF application to handle appropriately the concepts of Binding and Commands?
I mean, need I write some own wrappers for these library classes in order to implement interfaces such as ICommand or should this be done directly in the library itself?
Some code to get my question more comprehensible:
From the library:
public class Item
{
public string Name { get; set; }
public void DoSomething() { throw new NotImplementedException; }
}
I want to implement the function DoSomething() in my XAML markup without any line of code in that .cs file since that is, from what I've read, the best practice.
(Assuming that an instance of Item is bound to the control)
<Button Command="{Binding DoSomething}"/>
Well, in order to do so, I need to implement the interface ICommand and create a command, but that is, as stated above, unclear to me since I'm using a library here.
Should I write my own Wrapper for the Item class of the API and implement the ICommand interface or is there any other way to archieve this? I've written the library by myself so changes are possible. I'm just not entirely sure about changing the library because if I do so, it is (possibly) bound to WPF.
Hi there if anything your ViewModel should handle any requests on your Model that's it's sole purpose, to get these things to work you need ICommand and if you want some more info here is link with a tutorial on RoutedCommands. If you have your Model and ViewModel defined then you can easily assign tasks to the particular Model through its VM.
P.S. I think you could treat your library as a Model and write a "wrapper" ViewModel to handle operations on it. HTH
UPDATE
Consider following:
class libClass
{
void method()
{
//do something here
}
}
code above would be your model and if you want it to be more readable you could do it this way
class libModel
{
private libClass _libClass;
public libClass LibClass { get; set; }
}
Note
You could implement INotfiyPropertyChanged in your Model to handle any changes if needed of course.
now in your VM how you use the Model
class ViewModel
{
private libModel _libModel;
public libModel LibModel { get; set; }
//after you set up your RoutedCommands
//I declare method within my VM to handle the RoutedCommands don't know
//if it works when you use Property Method
void VMMethod()
{
//use VM's property to invoke desired method from your lib
}
}
and voila! ready "wrapper" for your class with implementation in your VM.
Tip
If you want to know how to do the RoutedCommands here is a link to a tutorial.
Suppose I have a CarSystem class, which has a collection of CarParts objects in it. Now I wish to write a stereo plugin to the system, and I wish the format of all plugins to be:
public interface ICarPluginMetaData
{
string Name {get;}
string Description {get;}
int Status {get; set;}
}
public interface ICarPlugin
{
void int setStatus(int newStatus);
}
[Export(typeof(ICarPlugin))]
[ExportMetaData("Name", "Stereo")]
[ExportMetaData("Description","Plays music")]
[ExportMetaData("Status", 0)]
public class StereoPlugin : ICarPlugin
{
[ICarPluginImport("FrontSpeakers")]
public CarPart myFrontSpeakersPointer;
[ICarPluginImport("RearSpeakers")]
public CarPart myRearSpeakersPointer;
[ICarPluginImport("subwoofer")]
public CarPart mysubwooferPointer;
[Export]
public void setStatus(int newStatus)
{
Status = newStatus;
}
}
Now in my CarSystem class, I define exports, however the default behavior is to create 1 static object, and hand it to all those importing it; how would I be able to do the following:
[ExportAsThreadsafe]
public CarPart FrontSpeakers
[ExportAsThreadsafe]
public CarPart RearSpeakers
[ExportAsThreadsafe]
public CarPart Subwoofer
[ExportAsThreadsafe]
public CarPart DashLights
so that when I create a second plugin, running on a separate thread, I get a threadsafe connection to the actual object for all plugins?
One way to provide thread safety in MEF is to perform a separate independent MEF composition in each thread. Everything constructed in that composition is then local to that thread. Any cross-thread access is under your control and you can use normal thread safety techniques.
I'm not clear on whether you want to load multiple stereo plugins and have them available to / bound to one global CarSystem, or if you are simply talking about having multiple CarSystems in different threads, independent of each other. You can do the latter by MEF composing the CarSystem with a particular stereo plugin inside of a thread.
Here's what I've ended up doing (in pseudocode):
Foreach plugin dynamically loaded
{
//Via reflection
Foreach field in the plugin
{
See if the field has an attribute attached
Find the field who's name is the same as it's attribute's name
{
Using some lookup method, find the object in the CarSystem
collection who's name is the same as the attribute name.
create a concurrencyQueue using proxy object
call field.SetValue(pluginObject, new Proxy Object) //Reflection call
}
}
}
I basically said, "screw MEF doing this automatically" and did it myself, using Reflection and custom Attributes. I used MEF to do one way messaging, but for plugin's that needed to alter objects in the CarSystem I used my custom "MEF" style.