If all you want to do is plot the cell the interop solution is fine, but you would be limited to using the interop API on the returned element. There is no easy way of passing the element back and forward that I am aware of.
Also, I do not think update 4 is when this was introduced, just when it was added to the documentation. If i am not mistaken, you could always access the interop using "Bentley.MicroStation.InteropServices.Utilities.ComApp;"
Below is my implementation of shared cells, some extension methods may be missing which you can grab from the link I posted prior..
internal class SharedCell { private readonly List<Element> _elements = new List<Element>(); private SharedCell() { } public int Count { get { return _elements.Count; } } private void Add(IEnumerable<Element> elements) { _elements.AddRange(elements); } private void Add(Element ele) { _elements.Add(ele); } private void Clear() { _elements.Clear(); } public static List<CellInformation> GetLoadedCellInfo(bool displayOnly = true) { List<CellInformation> results = new List<CellInformation>(); CellLibraryCollection c = new CellLibraryCollection(CellLibraryOptions.Default); foreach (CellLibraryInfo info in c) { StatusInt error; DgnModel cellModel = null; if (displayOnly == false) cellModel = info.File.LoadRootModelById(out error, info.File.FindModelIdByName(info.Name)); results.Add(new CellInformation(info.Name, info.Description, info.Type, info.File.GetFileName(), info.IsAnnotation, cellModel)); } return results; } public static CellInformation GetCellInfoByName(string name) { CellLibraryCollection c = new CellLibraryCollection(CellLibraryOptions.Default); foreach (CellLibraryInfo info in c) { StatusInt error; DgnModel cellModel = info.File.LoadRootModelById(out error, info.File.FindModelIdByName(info.Name)); if (info.Name.ToLower() == name.ToLower()) return new CellInformation(info.Name, info.Description, info.Type, info.File.GetFileName(), info.IsAnnotation, cellModel); } return null; } public static SharedCellElement GetCellElement(string cellName, DPoint3d position, bool toUor, double userScale = 1.0) { CellInformation cellInfo = GetCellInfoByName(cellName); if (cellInfo == null) return null; return GetCellElement(cellInfo, position, toUor, userScale); } public static SharedCellElement GetCellElement(CellInformation cellInfo, DPoint3d position, bool toUor, double userScale = 1.0) { if (cellInfo.Model == null) { Debug.Print("Cell Info does not contain a model. Returning null"); return null; } SharedCell sharedCell = new SharedCell(); if (!CheckIfCellDefinitionExists(cellInfo.Name)) { // Iterate over every element of the cells model and recreate it in our active model. IEnumerator<Element> elements = cellInfo.Model.GetElements().GetEnumerator(); // Calculate the conversion factor from the cell model to the active model. ModelInfo cellModelInfo = cellInfo.Model.GetModelInfo(); UnitDefinition cellMasterUnits = cellModelInfo.GetMasterUnit(); ModelInfo activeModelInfo = Ms.GetActiveModel().GetModelInfo(); UnitDefinition activeMasterUnits = activeModelInfo.GetMasterUnit(); double scale; activeMasterUnits.GetConversionFactorFrom(out scale, cellMasterUnits); // Scale the element to the model units. DTransform3d trns = new DTransform3d(scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, scale, 0); TransformInfo tInfo = new TransformInfo(trns); while (elements.MoveNext()) { Element ele = elements.Current; // If we include these elements, microstation crashes. :( I think it is just the DgnApplicationData (Meta data attached to DGN) if (ele.ElementType == MSElementType.MicroStation) continue; Element newEle = ele.Clone(); newEle.FromUor(cellInfo.Model); newEle.ApplyTransform(tInfo); newEle.ToUor(); sharedCell.Add(newEle); } sharedCell.CreateSharedCellDefinition(cellInfo.Name, cellInfo.Description, cellInfo.Type == CellLibraryType.Point, cellInfo.IsAnnotation); elements.Dispose(); } DPoint3d origin = position.ToUor(); SharedCellElement cellElement = sharedCell.GetElement(cellInfo.Name, origin, DMatrix3d.Identity); DTransform3d finalTrns = DTransform3d.FromUniformScaleAndFixedPoint(origin, userScale); TransformInfo finaltInfo = new TransformInfo(finalTrns); cellElement.ApplyTransform(finaltInfo); if (!toUor) cellElement.FromUor(); if(cellInfo.IsAnnotation) cellElement.AddAnnotationScale(Ms.GetActiveModel()); return cellElement; } private SharedCellElement GetElement(string cellName, DPoint3d origin, DMatrix3d rotation) { SharedCellElement elem = new SharedCellElement(_model, null, cellName, origin, rotation, DPoint3d.FromXYZ(1,1,1)); return elem; } private static bool CheckIfCellDefinitionExists(string cellName) { Element existingDefinition = SharedCellQuery.FindDefinitionByName(cellName, Ms.GetActiveDgnFile()); if (existingDefinition == null) return false; existingDefinition.Dispose(); return true; } private void CreateSharedCellDefinition(string cellName, string cellDescription, bool isPointCell, bool isAnnotation) { // Left out description. Caused crash with someones library, maybe if description is empty? SharedCellDefinitionElement definition = new SharedCellDefinitionElement(_model, cellName) { IsAnnotation = isAnnotation, IsPointCell = isPointCell }; foreach (Element element in _elements) { definition.AddChildElement(element); } definition.AddChildComplete(); definition.AddToModel(); } }