Orchard modul több cégre szabása (archív)

Topics: Magyar (Hungarian)
Developer
Apr 14, 2013 at 10:57 PM
bofa mondta 2012. szeptember 5. 15:19

Sziasztok!

A következő a problémám. Adott egy modul az Orchardban, a hozzá tartozó controllereket cégtől függően szeretném betölteni.

ezt úgy értem el, hogy létrehoztam egy interfacet IMyController néven. Semmit nem tud, csak van. :)

létrehoztam egy őst ami így nézki:

namespace MyNameSpace.Orchard.Modules

{

public class Controller : System.Web.Mvc.Controller, IMyController

{

}

}

az összes cotrollerem ebből származik.

erre azért volt szükség, hogy ShellContainerFactory a megfelelő controllereket töltse be.

string <b>CegNev</b>= "ACEG";

if (serviceKeyType.GetInterfaces().Where(t => t.FullName.Contains("IMyController ")).Any() == false || serviceKeyType.FullName.Contains(<b>CegNev</b>))

RegisterType(builder, item)

.EnableDynamicProxy(dynamicProxyContext)

.Keyed<IController>(serviceKeyName)

.Keyed<IController>(serviceKeyType)

.WithMetadata("ControllerType", item.Type)

.InstancePerDependency()

.OnActivating(e => {

var controller = e.Instance as Controller;

if (controller != null)

controller.ActionInvoker = (IActionInvoker)e.Context.ResolveService(new TypedService(typeof(IActionInvoker)));

});

ha létezik egy

namespace MyNameSpace.Orchard.Modules.Szerzodes.Controllers

{

public class HomeController : MyNameSpace.Orchard.Modules.Controller

{

}

}

namespace MyNameSpace.Orchard.Modules.Szerzodes.Controllers.ACEG

{

public class HomeController : MyNameSpace.Orchard.Modules.Szerzodes.Controllers.HomeController

{

}

}

namespace MyNameSpace.Orchard.Modules.Szerzodes.Controllers.BCEG

{

public class HomeController : MyNameSpace.Orchard.Modules.Szerzodes.Controllers.HomeController

{

}

}

a cég névnek csináltam beállítási lehetőséget a Site -> Settings-ben az jól is működik. A controlokban le is tudom kérni az IOrchardServices interface-n keresztül.

Viszont ehhez a service-hez nem férek hozzá a ShellContainerFactory-ban.

Tudnátok segíteni, hogy minél kevesebb Orchard forrás átírásával hogyan tudnám megvalósítani?

A vastagon szedett változót szeretném betölteni a beállításokból.

segítséget előre is köszönöm.

Üdv: Bofa




bofa mondta 2012. szeptember 5. 15:58

egyszerűbben leírva:

hozzáférek valahogy a ShellContainerFactory a weboldal beállításához, ami az adatbázisban van eltárolva?




Piedone mondta 2012. szeptember 5. 17:09

Szerintem Autofac modul írásánál bonyolultabb megoldás erre a problémára nincs is :-).

Az aktuális tenant beállításaihoz az ISiteService-en keresztül férsz hozzá a legegyszerűbben. Az azzal lekérdezhető ISite objektum IContent derivátum, tehát "castolhatod" a saját beállításaid partjának típusára, ha hozzáadtál beállításokat a Site content type-hoz egy part formájában.

Ha jól értem, akkor te tenantonként akarsz néhány, az oldalon használt információt megváltoztatni. Ezeket talán a legkézenfekvőbb adatbázisban, az oldal beállításai között letárolni, így: http://www.szmyd.com.pl/blog/how-to-add-settings-to-your-content-parts-and-items#.UEdqryLYe4o Ha a view-kban ennél több testreszabásra is szükség van, akkor inkább témából shape override, amit ajánlani tudok.




bofa mondta 2012. szeptember 5. 17:59

szia!

az linket, amit küldtél köszönöm. Azt meg is csináltam és hozzá is férek a controllból az adathoz. Nekem sokkal "előbb" kellene. még a névterek felolvasásakor.

Nem lesz több tenant-om. Cégenként külön szerveren fog futni a honlap. Például az előfordulhat, hogy cégenként más lesz a szerződés controll. Ezt oldom meg az autofac-kal. (Nem én találtam ki. :) ). A problémám, hogy az ISiteService-hez nem férek hozzá a ShellContainerFactory-ban.

A View-kkal később foglalkozom, de köszi a tippet. ;)




Piedone mondta 2012. szeptember 6. 6:21

Pontosan mit szeretnél elérni? Mert úgy érzem nem értem pontosan :-). Ha cégenként (oldalanként) más lehet a controller, akkor miért nem írsz egyszerűen több controllert, esetleg egy közös ősből származtatva? Akár minden cégnek egy-egy külön cégspecifikus modulban, egy közös modult, amiben az ős van, megjelölve dependencyként?




bofa mondta 2012. szeptember 6. 9:11

Megpróbálom elmagyarázni. :)

adott 10 cég akinek készítem a programot.

van benne több funkció is. Pl. szerződés nyilvántartás, munkalap nyilvántartás.

a 10 cégből 7-nél egyforma 3-nál van eltérés. Ehhez a 3-hoz különböző névterekben de azonos néven szeretnék létrehozni controll-okat. Nem szeretném külön dll-be rakni ezeket.

Nem szeretnék ennyi modult létrehozni, mert akkor rövid idő alatt lenne 100-as nagyságrendben modulom. :) annak a frissítése elég nehézkes.

Tartok tőle, hogy nem tudom megfelelően elmagyarázni a dolgot.




Piedone mondta 2012. szeptember 6. 18:21

Akkor ami itt fontos, hogy mi pontosan az az eltérés.

Ha csak adatbeli eltérés van (azaz olyasmiről van szó, amit a példában illusztráltál), akkor az egyértelműen adatbázisba vagy valamilyen config fájlba (amit pl. az App_Data mappába raksz) kívánkozik.

Ha működésbeli különbség van (azaz a controllerek magja ugyanaz, de némi eltérés a működésükben van), akkor indokolt, hogy ezek külön controllerben legyenek. Ekkor azonban én továbbra sem a névtérrel különböztetném őket meg, mert az MVC úgy van tervezve, hogy ne vegye figyelembe a controllerek névterét (ez jó, mert így akármilyen névtérbe rakhatsz egy controllert, működni fog, amíg implementálja az IController interface-t). Ha nem akarsz cégenként modulokat, akkor viszont én különbözőképp elnevezett controllereket javasolnék (pl. Cég1Controller), és ha mindenképp fontos az, hogy az elérési út ugyanaz legyen minden cégnél, akkor a céghez tartozó témában (mert gondolom az azért külön van) egy IRouteProviderben állítsd be a controller route-ját a kívántra.




bofa mondta 2012. szeptember 7. 13:40

kicsit átgondoltam. Kihagyom az autofac-ot. helyette a már kész saját ős controllerembe teszek egy egy függvényt, amit minden controller action meghív és az szépen megkeresi a metódust és meghívja.

Type T = this.GetType();

List<MethodInfo> OneMethod = T.GetMethods().Where(m => m.Name.ToUpper().IndexOf((_actionName + _cegNev).ToUpper()) > -1 && m.MemberType == System.Reflection.MemberTypes.Method).ToList();

if (OneMethod.Count == 0)

{

OneMethod = T.GetMethods().Where(m => m.Name.ToUpper().IndexOf((_actionName + "Default").ToUpper()) > -1 && m.MemberType == System.Reflection.MemberTypes.Method).ToList();

}

if (OneMethod != null) OneMethod.FirstOrDefault().Invoke(this, null);

valahogy így. :)




Piedone mondta 2012. szeptember 7. 19:38

Ha jól értem ez arra hivatott, hogy az ősben egy metódus meghívjon egy (a cégnevet is tartalmazó nevű) metódust. Hacsak nem szükséges valami különleges okból az, hogy a metódus tartalmazza cég nevét (ami nem gondolom, hogy kellene), akkor az ősben simán lehetne egy abstract metódus, az ős metódusa azt hívná, a leszármazottban pedig implementálhatod az abstract metódust.

De továbbra is azt javasolnám, hogy elsősorban adatbázisban tárolt beállításokban és témákból elvégezhető testreszabásokban (route átállítása, shape template override) gondolkozz, ne controller öröklésben.